差分数组解算法题

这题可用差分数组来解:力扣1893

什么是差分数组?

假如有个原数组

int[] origin = new int[]{1,2,3,4,5,6,7,8};

那么这个range数组的差分数组就是origin数组相邻元素的差组成的数组。

int n = origin.length;

int[] diff = new int[n];
for(int i=0; i<n; i++){
    if(i==0) diff[i] = origin[i];
    diff[i] = origin[i]-origin[i-1];
}

差分数组的作用

当原数组中的某段区间内的元素同时增加/减去一个相同的值的时候,可以不必对原数组区间内的元素一个一个更新,只要更新对应差分数组的区间端点即可。
栗子.

  • 老方法
        //对原数组[2,7]区间的数整体加3
        int left = 2,right = 7;
        
        //传统方法,复杂度O(n)
        while(left<=right){
            origin[left++] += 3;
        }
        
  • 新方法
        //对原数组[2,7]区间的数整体加3
        int left = 2,right = 7;
        //引入差分数组后的方法,复杂度O(1)
        diff[left] += 3;
        diff[right+1] -= 3;

新方法怎么还原修改后的原数组呢?

只要把diff数组求前缀和就可以了。

for(int i=0; i<diff.length; i++){
   if(i==0) origin[i] = diff[i];
   origin[i] = origin[i-1]+diff[i];
}

为什么求前缀和就能得到原数组的更新后状态呢?

因为我们修改的是整体区间的值,而且修改的大小还是一样的(这两个条件缺一不可)。当这两个条件都满足的情况下,区间内对应的差分数组的值是不变的,我们只要更新区间端点的值即可。

说明:图片来自此处

补充,虽然通过差分数组还原新数组复杂度还是O(n),相比于老方法没有提高,但是,若是修改次数大于1呢?频繁修改呢?我们用新方法可以在m次修改后,以O(m+n)的复杂度获得新数组,老方法的复杂度是O(m*n)。

再补充,由于还原新数组的方法是求动态数组的前缀和,可以想到把差分数组与树状数组结合。将上述复杂度提升为O(M+lgN)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值