差分数组的原理

现在有一数组nums,构造其差分数组diff

int[] diff = new int[nums.length];
// 差分数组的第一个元素是原数组的第一个值
diff[0] = nums[0];
for(int i=1;i<nums.length;i++){
  diff[i] = nums[i]-num[i-1]
}

从上面的差分数组的构造,diff[i] = nums[i]-num[i-1]可以推出nums[i] = diff[i]+nums[i-1];

从而可以得到从差分数组推出原数组的算法代码,如下:

int[] res = new Int[diff.length];
res[0] = diff[0];
for(int i=0;i<res.length;i++){
  res[i] = res[i-1]+diff[i];
}

我们知道于前缀和数组用于数组保持不变得场景,差分数组使用于对数组的频繁的增减的操作场景

那么现在假设对数组nums[i...j]范围的元素加3,怎样用差分数组实现呢;

由公式res[i] = res[i-1]+diff[i];可知我们可以让diff[i]加3,diff[j+1]减3来实现


原理很简单,回想 diff 数组反推 nums 数组的过程,diff[i] += 3 意味着给 nums[i..] 所有的元素都加了 3

因为diff[i]+3会传递到res[i]+3从而使得res[i+1]得到3

,然后 diff[j+1] -= 3 又意味着对于 nums[j+1..] 所有元素再减 3,那综合起来,是不是就是对 nums[i..j] 中的所有元素都加 3 了

根据上述的推论,可以构建以下差分数组的工具类

复制代码
class Difference{

    //差分数组
    private int[] diff;
    
   // 够着差分数组
    public Difference(int[] nums){
      diff[0] = nums[0];
      for(int i=1;i<nums.length;i++){
            diff[i] = res[i]-res[i-1];
       }
   }

    /* 给闭区间 [i, j] 增加 val(可以是负数)*/
    public void increment(int i, int j, int val) {
        diff[i] += val;
        // 如果j+1等于diff.length,说明是给包括i后面的所有元素都加val,就不需要再有减去的操作
        if (j + 1 < diff.length) {
            diff[j + 1] -= val;
        }
    }
    
   // 构造结果数组,对原数组nums操作后的数组
   public int[] result(){
    int[] res = new int[diff.length];
        // 根据差分数组构造结果数组
        res[0] = diff[0];
        for (int i = 1; i < diff.length; i++) {
            res[i] = res[i - 1] + diff[i];
        }
        return res;
    }
}
复制代码

 

posted @   MintMin  阅读(128)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示