差分数组的原理
现在有一数组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; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!