370. Range Addition
Assume you have an array of length n initialized with all 0’s and are given k update operations.
Each operation is represented as a triplet: [startIndex, endIndex, inc] which increments each element of subarray A[startIndex … endIndex] (startIndex and endIndex inclusive) with inc.
Return the modified array after all k operations were executed.
Example:
Input: length = 5, updates = [[1,3,2],[2,4,3],[0,2,-2]]
Output: [-2,0,3,5,3]
Explanation:
Initial state:
[0,0,0,0,0]
After applying operation [1,3,2]:
[0,2,2,2,0]
After applying operation [2,4,3]:
[0,2,5,5,3]
After applying operation [0,2,-2]:
[-2,0,3,5,3]
Hint:
- Thinking of using advanced data structures? You are thinking it too complicated.
- For each update operation, do you really need to update all elements between i and j?
- Update only the first and end element is sufficient.
- The optimal time complexity is O(k + n) and uses O(1) extra space.
方法0:
方法1:
官方题解:https://leetcode.com/problems/range-addition/solution/
思路:
根据hint, 对每一次range addition只需要改动startIdx 成为result[startIdx] += val, 同时改动endIdx成为result[endIdx + 1] -= val。为什么要这么做?
Intuition
There is only one read query on the entire range, and it occurs at the end of all update queries. Additionally, the order of processing update queries is irrelevant.
Cumulative sums or partial_sum operations apply the effects of past elements to the future elements in the sequence.
也就是说,最后会利用prefix sum的累加性质把+val的效果扩散到startIdx以后。那么就需要在endIdx + 1 及其以后的位置抵消掉这个effect,也就是从endIdx + 1开始-val。那么最后求prefic的结果即可。
易错点
- 边界处理
Complexity
Time complexity: O(n+k). Each of the k update operations is done in constant O(1) time. The final cumulative sum transformation takes O(n) time always.
Space complexity : O(1). No extra space required.
class Solution {
public:
vector<int> getModifiedArray(int length, vector<vector<int>>& updates) {
vector<int> result(length + 1, 0);
for (auto a: updates){
result[a[0]] += a[2];
result[a[1] + 1] -= a[2];
}
for (int i = 1; i < length; i++){
result[i] = result[i - 1] + result[i];
}
result.pop_back();
return result;
}
};
二刷:
class Solution {
public:
vector<int> getModifiedArray(int length, vector<vector<int>>& updates) {
vector<int> nums(length, 0);
for (auto v: updates) {
nums[v[0]] += v[2];
if (v[1] != length - 1) {
nums[v[1] + 1] -= v[2];
}
}
for (int i = 1; i < length; i++) {
nums[i] = nums[i - 1] + nums[i];
}
return nums;
}
};