307. Range Sum Query - Mutable
https://leetcode.com/problems/range-sum-query-mutable/description/
求解范围内max/min/sum/count且范围内的元素值会不断改变(但总size不变),线段树和二叉索引树是常用方法。除了常规真的定义一颗二叉树,每个结点有范围和感兴趣的值外,还可以用完全二叉树的表示方法即一个数组。线段树叶子结点表示范围大小为1的点,即原nums数组元素,放在N-1~2 N - 1。倒着遍历,叶结点两两合并的父节点存更大范围的和,nodes[i] = nodes[i * 2] + nodes[i * 2 + 1]。这样建好树后每次更新时也是倒着先从叶结点层层往上更新值。求sumRange也是从叶子开始,用两个指针分别指向最外面的两个元素,如果i指向的是右子结点说明它代表的区间已经是边界,不能把它父结点的算进来,因此把它的值加上并把范围缩小1个。j同理。当i > j时遍历结束。解法参考了这里。
/*
* @lc app=leetcode id=307 lang=cpp
*
* [307] Range Sum Query - Mutable
*
* https://leetcode.com/problems/range-sum-query-mutable/description/
*
* algorithms
* Medium (29.96%)
* Likes: 804
* Dislikes: 66
* Total Accepted: 79.7K
* Total Submissions: 264.7K
* Testcase Example: '["NumArray","sumRange","update","sumRange"]\n[[[1,3,5]],[0,2],[1,2],[0,2]]'
*
* Given an integer array nums, find the sum of the elements between indices i
* and j (i ≤ j), inclusive.
*
* The update(i, val) function modifies nums by updating the element at index i
* to val.
*
* Example:
*
*
* Given nums = [1, 3, 5]
*
* sumRange(0, 2) -> 9
* update(1, 2)
* sumRange(0, 2) -> 8
*
*
* Note:
*
*
* The array is only modifiable by the update function.
* You may assume the number of calls to update and sumRange function is
* distributed evenly.
*
*
*/
class NumArray {
private:
vector<int> nodes;
int N;
public:
NumArray(vector<int>& nums) {
N = nums.size();
nodes.resize(2 * N);
// nums作为叶子
for (int i = N; i < 2 * N; ++i) {
nodes[i] = nums[i - N];
}
for (int i = N - 1; i >= 0; --i) {
nodes[i] = nodes[i * 2] + nodes[i * 2 + 1];
}
}
void update(int i, int val) {
nodes[i += N] = val;
while (i > 0) {
nodes[i / 2] = nodes[i] + nodes[i ^ 1];
i /= 2;
}
}
int sumRange(int i, int j) {
int sum = 0;
for (i += N, j += N; i <= j; i /= 2, j /= 2) {
// 左边界为右结点, 加上自己,并把范围缩小1。
if ((i & 1) == 1) sum += nodes[i++];
// 右边界为左结点, 加上自己,并把范围缩小1。
if ((j & 1) == 0) sum += nodes[j--];
}
return sum;
}
};
/**
* Your NumArray object will be instantiated and called as such:
* NumArray* obj = new NumArray(nums);
* obj->update(i,val);
* int param_2 = obj->sumRange(i,j);
*/
Previous1519. Number of Nodes in the Sub-Tree With the Same LabelNext428. Serialize and Deserialize N-ary Tree
Last updated
Was this helpful?