Given an integer array nums
, handle multiple queries of the following types:
- Update the value of an element in
nums
. - Calculate the sum of the elements of
nums
between indicesleft
andright
inclusive whereleft <= right
.
Implement the NumArray
class:
NumArray(int[] nums)
Initializes the object with the integer arraynums
.void update(int index, int val)
Updates the value ofnums[index]
to beval
.int sumRange(int left, int right)
Returns the sum of the elements ofnums
between indicesleft
andright
inclusive (i.e.nums[left] + nums[left + 1] + ... + nums[right]
).
Example 1:
Input ["NumArray", "sumRange", "update", "sumRange"] [[[1, 3, 5]], [0, 2], [1, 2], [0, 2]] Output [null, 9, null, 8] Explanation NumArray numArray = new NumArray([1, 3, 5]); numArray.sumRange(0, 2); // return 1 + 3 + 5 = 9 numArray.update(1, 2); // nums = [1, 2, 5] numArray.sumRange(0, 2); // return 1 + 2 + 5 = 8
Constraints:
1 <= nums.length <= 3 * 10^4
-100 <= nums[i] <= 100
0 <= index < nums.length
-100 <= val <= 100
0 <= left <= right < nums.length
【C++】
借用线段树:用来查询某一区间对应的信息(如最大值,最小值,区间和等)。
class NumArray {
vector<int> tree; // segment tree
int n;
public:
NumArray(vector<int>& nums) {
n = nums.size();
tree = vector<int>(n*2);
for (int i = 2*n-1; i >= n; i--) {tree[i] = nums[i-n];}
for (int i = n-1; i > 0; i--) {tree[i] = tree[2*i] + tree[2*i+1];}
}
void update(int index, int val) {
index += n;
tree[index] = val;
while (index > 1) {
index >>= 1;
int newval = tree[2*index] + tree[2*index+1];
if (tree[index] == newval) {return;}
tree[index] = newval;
}
}
int sumRange(int left, int right) {
left += n;
right += n + 1;
int sum = 0;
while(left < right) {
if (left&1 == 1) {sum += tree[left++];}
if (right&1 == 1) {sum += tree[--right];}
left >>= 1;
right >>= 1;
}
return sum;
}
};
/**
* Your NumArray object will be instantiated and called as such:
* NumArray* obj = new NumArray(nums);
* obj->update(index,val);
* int param_2 = obj->sumRange(left,right);
*/
【Java】
class NumArray {
private int[] tree; // segment tree
private int n;
public NumArray(int[] nums) {
n = nums.length;
tree = new int[n*2];
for (int i = 2*n-1; i >= n; i--) {tree[i] = nums[i-n];}
for (int i = n-1; i > 0; i--) {tree[i] = tree[2*i] + tree[2*i+1];}
}
public void update(int index, int val) {
index += n;
tree[index] = val;
while (index > 1) {
index >>= 1;
int newval = tree[2*index] + tree[2*index+1];
if (tree[index] == newval) {return;}
tree[index] = newval;
}
}
public int sumRange(int left, int right) {
left += n;
right += n + 1;
int sum = 0;
while(left < right) {
if ((left&1) == 1) {sum += tree[left++];}
if ((right&1) == 1) {sum += tree[--right];}
left >>= 1;
right >>= 1;
}
return sum;
}
}
/**
* Your NumArray object will be instantiated and called as such:
* NumArray obj = new NumArray(nums);
* obj.update(index,val);
* int param_2 = obj.sumRange(left,right);
*/
参考文献