Loading...Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.https://leetcode.com/problems/range-sum-query-mutable/
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 indices left and right inclusive where left <= right.
Implement the NumArray class:
- NumArray(int[] nums) Initializes the object with the integer array nums.
- void update(int index, int val) Updates the value of nums[index] to be val.
- int sumRange(int left, int right) Returns the sum of the elements of nums between indices left and right 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
借用线段树:用来查询某一区间对应的信息(如最大值,最小值,区间和等)。
class NumArray {
vector tree; // segment tree
int n;
public:
NumArray(vector& nums) {
n = nums.size();
tree = vector(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;
}
};
【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;
}
}
参考文献
【1】数据结构与算法(十)线段树(Segment Tree)入门
【2】线段树(segment tree),看这一篇就够了


![LeetCode-307. Range Sum Query - Mutable [C++][Java] LeetCode-307. Range Sum Query - Mutable [C++][Java]](http://www.mshxw.com/aiimages/31/857331.png)
