差分数组的原理

对于一个数组

nums  = [1,5,2,6,3,-1],

它的前缀和数组(前n项和)为

f = [1,6,8,14,17,16],

它的差分数组 (d[ i ] = nums[ i ]-nums[ i - 1 ])

d = [1,4,-3,4,-3,-4],而差分数组d的前缀和数组就是nums

而当数组区间 [ l ,r ] 进行加减操作

nums[ l , r ]+v

时,无需对每一个数字进行独立的操作,只需对数组的差分左右侧进行操作,使

d[ l ] += v ,d[ r+1 ] -= v,

即可通过该差分的前缀和获得操作后的数组

    int[] nums = {1,5,2,6,3,-1};//基本的一个nums
    int[] f = {1,6,8,14,17,16};//nums的前n项和,即前缀和
    int[] d = {1,4,-2,4,-3,-4};//nums的差分,即nums[i]-nums[i-1]
    int[] df = new int[6];//nums的差分的前缀和

    nums = {nums[0],nums[1],nums[2],nums[3],nums[4],nums[5]};//nums的每一项都是nums[i]
    f = {nums[0],f[1],f[2],f[3],f[4],f[5]};//差分的每一项都是f[i]
    f = {nums[0],//f[i]即是前n项和
            nums[0]+nums[1],
            nums[0]+nums[1]+nums[2],
            nums[0]+nums[1]+nums[2]+nums[3],
            nums[0]+nums[1]+nums[2]+nums[3]+nums[4],
            nums[0]+nums[1]+nums[2]+nums[3]+nums[4]+nums[5]};
    d = {nums[0],//差分则是nums[i]-nums[i-1],i=1时取nums的第一项
            nums[1]-nums[0],
            nums[2]-nums[1],
            nums[3]-nums[2],
            nums[4]-nums[3],
            nums[5]-nums[4]}
    df = {nums[0],//再计算差分的前n项和
            nums[1]-nums[0]+nums[0],//可以消去左右的nums[0]
            nums[1]+nums[2]-nums[1],//这里左右的nums[0]已经被消去了,nums[1]也会被消去
            nums[2]+nums[3]-nums[2],
            nums[3]+nums[4]-nums[3],
            nums[4]+nums[5]-nums[4]
    }
    df = {nums[0],nums[1],nums[2],nums[3],nums[4],nums[5]//最终得到的又是nums
    }
    nums = {1,5,2,6,3,-1};
    nums[2,4]+5
    nums[1,2]-4
    nums[3,5]+1
    ->
    nums = {1,1,3,12,9,0}//执行所有操作之后的nums
    d = {1,4,-2,4,-3,-4}
    //关于区间[l,r]内所有数执行加减操作可视作nums[l]+v,nums[r+1]-v
    d[2,4]+5 -> d[2]+5,d[5]-5//d[l]+v,d[r+1]-v
    d[1,2]-4 -> d[1]-4,d[3]+4
    d[3,5]+1 -> d[3]+1,d[6]+1//这里d[6]不存在,取0
    ->
    {1,0,2,9,-3,-9}//执行操作后的差分数组
    df = {1,1,3,12,9,0}//差分数组的前缀和,执行正常流程的原数组一致

 原理解释:

由上面的解释可知,差分数组的前n项和就是原数组,当区间[ l , r ]进行减操作时,只要将 l 减去v,那么下标为 l 之后的前n项和都会减少v,并且 l 之前的前n项和都保持正常,但要保证 r 后面的数字不受影响就应当再补偿减去的v,所以会在 r+1 处加上v,如此一来 r 之后的前n项和又会正常得出,最后取差分的前缀和即是执行操作后的数组。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值