🤵♂️ 个人主页: @AI_magician
📡主页地址: 作者简介:CSDN内容合伙人,全栈领域优质创作者。
👨💻景愿:旨在于能和更多的热爱计算机的伙伴一起成长!!🐱🏍
差分和前缀和其实是互逆的,为什么呢🙌,我们看到最后就会明白
差分数组
差分和前缀和其实是互逆的,一维差分我们可以知道, a[i] 是 b[1]…b[i] 的前缀和,如果我们要对区间 [l , r] 中的数都加上一个数c的话只需要让 b[l] += c 并且 b[r + 1] -= c 即可,这样用差分数组构建新数组时,区间 [l , r] 中的数都会在原基础上加上c。
一维差分
LeetCode | 力扣 | 难度 |
---|---|---|
1094. Car Pooling | 1094. 拼车 | 🟠 |
蓝桥杯 重新排序 | 蓝桥杯 棋盘 |
差分数组的主要适用场景是频繁对原始数组的某个区间的元素进行增减
。(核心思想便是提前计算好差分数组,通过差分数组与原数组之前的等式关系,从而只需要一次操作便可以对某个区间的元素进行增减)
算法技巧「差分数组」,类似前缀和技巧构造的 preSum
数组,对 nums
数组构造一个 diff
差分数组
对区间 nums[i..j]
的元素全部加 3,让 diff[i] += 3
,再让 diff[j+1] -= 3
即可,只要花费 O(1) 的时间修改 diff
数组,就相当于给 nums
的整个区间做了修改。
注意:
1、差分数组的第一个元素和原数组一样,本质上是差分数组的数学公式逆推得到的结果。
把差分数组抽象成一个工具类便于调用,包含__init_
构造方法和 increment
方法和 result
方法,代码如下:
//java codes
// 差分数组工具类
class Difference {
// 差分数组
private int[] diff;
/* 输入一个初始数组,区间操作将在这个数组上进行 */
public Difference(int[] nums) {
assert nums.length > 0;
diff = new int[nums.length];
// 根据初始数组构造差分数组
diff[0] = nums[0];
for (int i = 1; i < nums.length; i++) {
diff[i] = nums[i] - nums[i - 1];
}
}
/* 给闭区间 [i, j] 增加 val(可以是负数)*/
public void increment(int i, int j, int val) {
diff[i] += val;
if (j + 1 < diff.length) {
diff[j + 1] -= val;
}
}
/* 返回结果数组 */
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];
}
// 用前缀和构造结果数组
num = res[0];
for (int i = 1; i < diff.length; i++) {
num += diff[i]
res[i] = num
}
return res;
}
}
# python codes
# 差分数组工具类
class Difference:
# 差分数组
def __init__(self, nums: List[int]):
assert len(nums) > 0 # 用断言捕获异常 比print好
self.diff = [0] * len(nums) # O(n) 复杂度
# 根据初始数组构造差分数组
self.diff[0] = nums[0]
for i in range(1, len(nums)):
self.diff[i] = nums[i] - nums[i - 1]
# 给闭区间 [i, j] 增加 val(可以是负数)
def increment(self, i: int, j: int, val: int) -> None:
self.diff[i] += val
if j + 1 < len(self.diff):
self.diff[j + 1] -= val
# 返回结果数组
def result(self) -> List[int]:
res = [0] * len(self.diff)
# 根据差分数组构造结果数组
res[0] = self.diff[0]
for i in range(1, len(self.diff)):
res[i] = res[i - 1] + self.diff[i]
return res
// c++ codes
// 差分数组工具类
class Difference {
// 差分数组
private:
int* diff;
/* 输入一个初始数组,区间操作将在这个数组上进行 */
public:
Difference(int* nums, int length) {
assert(length > 0);
diff = new int[length]();
diff[0] = nums[0];
for (int i = 1; i < length; i++) {
diff[i] = nums[i] - nums[i - 1];
}
}
/* 给闭区间 [i, j] 增加 val(可以是负数)*/
void increment(int i, int j, int val) {
diff[i] += val;
if (j + 1 < sizeof(diff) / sizeof(diff[0])) {
diff[j + 1] -= val;
}
}
/* 返回结果数组 */
int* result() {
int* res = new int[siz