什么是差分数组?「建议收藏」

什么是差分数组?「建议收藏」问题背景如果给你一个包含5000万个元素的数组,然后会有频繁区间修改操作,那什么是频繁的区间修改操作呢?比如让第1个数到第1000万个数每个数都加上1,而且这种操作时频繁的。此时你应该怎么做?很容易想到的是,从第1个数开始遍历,一直遍历到第1000万个数,然后每个数都加上1,如果这种操作很频繁的话,那这种暴力的方法在一些实时的系统中可能就拉跨了。因此,今天的主角就出现了——差分数组。…

大家好,又见面了,我是你们的朋友全栈君。

问题背景

如果给你一个包含5000万个元素的数组,然后会有频繁区间修改操作,那什么是频繁的区间修改操作呢?比如让第1个数到第1000万个数每个数都加上1,而且这种操作时频繁的。

此时你应该怎么做?很容易想到的是,从第1个数开始遍历,一直遍历到第1000万个数,然后每个数都加上1,如果这种操作很频繁的话,那这种暴力的方法在一些实时的系统中可能就拉跨了。

因此,今天的主角就出现了——差分数组。

 

算法原型

比如我们现在有一个数组arr,arr={0,2,5,4,9,7,10,0}

什么是差分数组?「建议收藏」

那么差分数组是什么呢?其实差分数组本质上也是一个数组,我们暂且定义差分数组为d,差分数组d的大小和原来arr数组大小一样,而且d[i]=arr[i]-arr[i-1](i≠0),且d[i]=0,它的含义是什么?就是原来数组i位置上的元素和i-1位置上的元素作差,得到的值就是d[i]的值。

所以,例子中的arr数组其对应的差分数组值如下图所示。

什么是差分数组?「建议收藏」

那么构造了这么个玩意有什么用呢?难道是来浪费宝贵的内存空间的?嗯,确实是来浪费宝贵的内存了,但是却换了时间上的高效。

现在我们有这么一个区间修改操作,即在区间1~4上,所有的数值都加上3.

什么是差分数组?「建议收藏」

我们不要傻傻地遍历arr数组的[1,4]范围,然后再分别给每个值加上3,我们此时更改差分数组d即可。

显而易见,差分数组d在[2,4]范围内的值都不用改变,只需要改变差分数组位置1和位置5的值即可,即d[1]=d[1]+3,而d[5]=d[5]-3,其余不变,为什么呢?因为差分数组的定义——d[i]=arr[i]-arr[i-1]

什么是差分数组?「建议收藏」

现在,我们如何根据差分数组d来推测arr中某一个位置的值呢?

比如,此时,我们想知道arr[1]的值,我们不能直接通过arr[1]得到原来的值,因为在区间修改的操作中我们并没有修改arr的值,因此我们必须从前往后遍历递推,由于d[0]=arr[0]-0(我们定义arr[0]的前一个数为0),那么arr[0]=d[0]=0,又由于d[1]=arr[1]-arr[0]=5,那么arr[1]=5+arr[0]=5。以此类推,由于d[2]=arr[2]-arr[1]=3,所以arr[2]=3+arr[1]=8。

 

总结

可以看到,如果需要对L~R范围内所有数都进行相同的操作,我们不需要从L~R遍历arr然后在每个值上进行相同操作,只需要在差分数组d中改变L和R+1的值即可。但是在查询arr数组中某个位置的数时,却要根据差分数组从前往后递推求值。

所以,该方法适用于区间频繁修改,而且这个区间范围是比较大的,离线查询的情况。

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/130341.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • getParameterValues 和 getParameter区别

    getParameterValues 和 getParameter区别一、getParameterValuesrequest.getParameterValues(Stringname)是获得如checkbox类(名字相同,但值有多个)的数据。接收数组变量,如checkobx类型二、getParameterrequest.getParameter(Stringname)是获得相应名的数据,如果有重复的名,则返回第一个的值….

    2022年7月22日
    23
  • Jenkins安装_jenkins sonar

    Jenkins安装_jenkins sonar前言jenkins的环境搭建方法有很多,本篇使用docker快速搭建一个jenkins环境。环境准备:mac/Linuxdockerdocker拉去jenkins镜像先下载jenkins镜

    2022年7月31日
    6
  • String与Integer相互转换「建议收藏」

    String与Integer相互转换「建议收藏」String与Integer相互转换//方法一:Integer类的静态方法toString()Integera=2;Stringstr=Integer.toString(a)//方法二:Integer类的成员方法toString()Integera=2;Stringstr=a.toString();//方法三:String类的静态方法valueOf()…

    2022年6月7日
    52
  • lspci 安装_ipswme下载的系统如何安装

    lspci 安装_ipswme下载的系统如何安装在原版的busy-box做出来的文件系统中,lspci命令只有两个选项:ynq>lspci-hlspci:invalidoption–‘h’BusyBoxv1.20.1(2012-11-2713:37:12MST)multi-callbinary.Usage:lspci[-mk]ListallPCIdevices-m

    2025年10月17日
    4
  • windows api编程入门_WindowsAPI调用DLL

    windows api编程入门_WindowsAPI调用DLLTranslateMessage是用来把虚拟键消息转换为字符消息。由于Windows对所有键盘编码都是采用虚拟键的定义,这样当按键按下时,并不得字符消息,需要键盘映射转换为字符的消息。TranslateMessage函数用于将虚拟键消息转换为字符消息。字符消息被投递到调用线程的消息队列中,当下一次调用GetMessage函数时被取出。当我们敲击键盘上的某个字符键时,系统将产生WM_KEYDOW

    2025年11月3日
    3
  • JQuery的Ajax跨域请求的

    JQuery的Ajax跨域请求的

    2022年2月2日
    39

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号