题目链接:https://leetcode.com/problems/range-sum-query-mutable/
题目:
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.
思路:
segment tree基础,创建tree用分治,求sum要注意所求的区间和节点区间的关系。
算法:
public class NumArray {
Node root = null;
public NumArray(int[] nums) {
root = create(nums, 0, nums.length - 1);
}
void update(int i, int val) {
update(root, i, val);
}
public int sumRange(int i, int j) {
return sum(root, i, j);
}
public class Node {
int lidx;
int ridx;
int val;
Node lchild;
Node rchild;
public Node(int lidx, int ridx, int val) {
this.lidx = lidx;
this.ridx = ridx;
this.val = val;
}
}
public Node create(int[] nums, int l, int r) {
if (l == r)
return new Node(l, r, nums[r]);
Node lchild = create(nums, l, (l + r) / 2);
Node rchild = create(nums, (l + r) / 2 + 1, r);
Node root = new Node(lchild.lidx, rchild.ridx, lchild.val + rchild.val);
root.lchild = lchild;
root.rchild = rchild;
return root;
}
public int sum(Node root, int l, int r) {
if (root.ridx < l || root.lidx > r)// 所求区间与节点区间不相交
return 0;
if (l <= root.lidx && root.ridx <= r)// 所求区间包含了 节点区间
return root.val;
return sum(root.lchild, l, r) + sum(root.rchild, l, r);//所求区间和节点区间相交
}
int diff = 0;// 需要从index叶节点 往上更新的值
public void update(Node root, int index, int newVal) {
if (root.lidx == root.ridx && index == root.lidx) {// 要更新的叶节点
diff = newVal - root.val;
root.val = newVal;
return;
}
if (index <= (root.lidx + root.ridx) / 2)
update(root.lchild, index, newVal);
else
update(root.rchild, index, newVal);
root.val += diff;
}
}