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();
}
}
这个解法并不是最优解,但是能很好的锻炼差分思维。