区间加法
大约 2 分钟
区间加法
假设你有一个长度为 n 的数组,初始情况下所有的数字均为 0,你将会被给出 k 个更新的操作。
其中,每个操作会被表示为一个三元组:[startIndex, endIndex, inc],你需要将子数组 A[startIndex ... endIndex](包括 startIndex 和 endIndex)增加 inc。
请你返回 k 次操作后的数组。
输入: length = 5, updates = [[1,3,2],[2,4,3],[0,2,-2]]
输出: [-2,0,3,5,3]
解释
初始状态:
[0,0,0,0,0]
进行了操作 [1,3,2] 后的状态:
[0,2,2,2,0]
进行了操作 [2,4,3] 后的状态:
[0,2,5,5,3]
进行了操作 [0,2,-2] 后的状态:
[-2,0,3,5,3]
思路分析:
构造差分数组
let diff = new Array[nums.length];
// 构造差分数组
diff[0] = nums[0];
for (let i = 1; i < nums.length; i++) {
diff[i] = nums[i] - nums[i - 1];
}
下标 | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
nums | 8 | 2 | 6 | 3 | 1 |
diff | 8 | -6 | 4 | -3 | -2 |
通过这个 diff
差分数组是可以反推出原始数组 nums
的,代码逻辑如下:
let res = new Array[diff.length];
// 根据差分数组构造结果数组
res[0] = diff[0];
for (let i = 1; i < diff.length; i++) {
res[i] = res[i - 1] + diff[i];
}
这样构造差分数组 diff
,就可以快速进行区间增减的操作,如果你想对区间 nums[i..j]
的元素全部加 3,那么只需要让 diff[i] += 3
,然后再让 diff[j+1] -= 3
即可:
下标 | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
diff | 8 | -6 | 4 | -3 | -2 |
操作 | i | j |
diff[i] += 3
意味着给 nums[i..]
所有的元素都加了 3,然后 diff[j+1] -= 3
又意味着对于 nums[j+1..]
所有元素再减 3,那综合起来,是不是就是对 nums[i..j]
中的所有元素都加 3 了
代码实现:
var getModifiedArray = function(length, updates) {
let arr = new Array(length).fill(0)
let diff = arr // 由于此问题中原始数组全是0,diff得到的也是全是0
updates.forEach(([i, j, val]) => {
arr[i] += val;
if (j + 1 < arr.length) {
arr[j + 1] -= val;
}
})
let res = [arr[0]];
// 根据差分数组构造结果数组
for (let i = 1; i < arr.length; i++) {
res[i] = res[i - 1] + arr[i];
}
return res
};