LeetCode-370.区间加法——差分方法

1.题目描述

假设你有一个长度为 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]

2.题解

这里参考的是labuladong的方法,大家可以去给东哥加油呀!
小而美的算法技巧:差分数组
首先构造差分数组,这里借一下东哥的图。从图中可以看出差分数组可以表示为:

diff[0] = nums[0];
for (int i = 1; i < nums.length; i++) {
	diff[i] = num[i] - diff[i - 1];
}

在这里插入图片描述
接着对区间数组进行操作,即给闭区间[i, j] 增加val (可以是负数)。
还以上图为例,我想对nums[2],nums[3]进行-3操作,那么只需对diff[2]进行-3操作。如果j + 1 < diff.length,也就是说j不是最后一个,则需要对j后面的值不进行操作,就需要最diff[j + 1] -=val;
最后对结果数组进行解释,从差分数组返回结果数组只需进行逆过程即可。这也是对区间[2, 3]进行操作只需对diff[2]进行-3的原因。因为diff[2] -3之后,在返回结果数组进行加和的时候后面会一直存在-3这个值。

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

整体代码如下:

// 差分数组工具类
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] - diff[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];
        }
        return res;
    }
}
class Solution {
    public int[] getModifiedArray(int length, int[][] updates) {
        int[] nums = new int[length];
        // 构造差分数组
        Difference df = new Difference(nums);
        // for (int i = 0; i < updates.length; i++) {
        //     int startIndex = updates[i][0];
        //     int endIndex = updates[i][1];
        //     int inc = updates[i][2];
        //     df.increment(startIndex, endIndex, inc);
        // }
        for (int[] update : updates) {
            int startIndex = update[0];
            int endIndex = update[1];
            int inc = update[2];
            df.increment(startIndex, endIndex, inc);
        }
        return df.result();
    }
}

这个解法并不是最优解,但是能很好的锻炼差分思维。
在这里插入图片描述

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值