给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点。
update(i, val) 函数可以通过将下标为 i 的数值更新为 val,从而对数列进行修改。
示例:
Given nums = [1, 3, 5]
sumRange(0, 2) -> 9
update(1, 2)
sumRange(0, 2) -> 8
说明:
数组仅可以在 update 函数下进行修改。
你可以假设 update 函数与 sumRange 函数的调用次数是均匀分布的。
思路: 线段树,递归到底返回维护sum即可。
class NumArray {
class SegementTreeNode {
int start,end;
SegementTreeNode left,right;
int sum;
public SegementTreeNode(int start,int end) {
this.start = start;
this.end = end;
this.left = null;
this.right = null;
this.sum = 0;
}
}
SegementTreeNode root = null;
public NumArray(int[] nums) {
root = buildTree(nums,0,nums.length-1);
}
private SegementTreeNode buildTree(int[] nums,int start,int end) {
if (start > end) return null;
SegementTreeNode root = new SegementTreeNode(start,end);
if (start == end) {
root.sum = nums[start];
} else {
int mid = (start + end) >>> 1;
root.left= buildTree(nums,start,mid);
root.right = buildTree(nums,mid + 1,end);
root.sum = root.left.sum + root.right.sum;
}
return root;
}
public void update(int i, int val) {
update(root,i,val);
}
private void update(SegementTreeNode root,int i,int val) {
if (root.start == root.end) {
root.sum = val;
} else {
int mid = (root.start + root.end) >>> 1;
if (i <= mid) {
update(root.left,i,val);
} else {
update(root.right,i,val);
}
root.sum = root.left.sum + root.right.sum;
}
}
public int sumRange(int i, int j) {
return sumRange(root,i,j);
}
private int sumRange(SegementTreeNode root,int i,int j) {
if (i == root.start && j == root.end) {
return root.sum;
} else {
int mid = (root.start + root.end) >>> 1;
if (j <= mid) {
return sumRange(root.left,i,j);
} else if (i >= mid + 1 ) {
return sumRange(root.right,i,j);
} else {
return sumRange(root.left,i,mid) + sumRange(root.right,mid+1,j);
}
}
}
}
/**
* 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);
*/