跳至主要內容

区间加法

Mr.He大约 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];
}
下标01234
nums82631
diff8-64-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 即可:

下标01234
diff8-64-3-2
操作ij

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
};