Description
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.
Problem URL
Solution
构建一个NumArray类,能给更新数组元素,并且返回数组index i 到 j的sum值。
Implement a segment tree node to solve this problem.
Code
class NumArray {
class SegmentTreeNode {
int start;
int end;
SegmentTreeNode left;
SegmentTreeNode right;
int sum;
public SegmentTreeNode(int start, int end){
this.start = start;
this.end = end;
this.left = null;
this.right = null;
this.sum = 0;
}
}
private SegmentTreeNode root = null;
public NumArray(int[] nums) {
root = buildTree(nums, 0, nums.length - 1);
}
private SegmentTreeNode buildTree(int[] nums, int start, int end){
if (start > end){
return null;
}
else{
SegmentTreeNode res = new SegmentTreeNode(start, end);
if (start == end){
res.sum = nums[start];
}
else{
int mid = start + (end - start) / 2;
res.left = buildTree(nums, start, mid);
res.right = buildTree(nums,mid + 1, end);
res.sum = res.left.sum + res.right.sum;
}
return res;
}
}
public void update(int i, int val) {
updateHelper(root, i, val);
}
private void updateHelper(SegmentTreeNode root, int pos, int val){
if (root.start == root.end){
root.sum = val;
}
else{
int mid = root.start + (root.end - root.start) / 2;
if (pos <= mid){
updateHelper(root.left, pos, val);
}
else{
updateHelper(root.right, pos, val);
}
//remember update root's sum value;
root.sum = root.left.sum + root.right.sum;
}
}
public int sumRange(int i, int j) {
return sumRangeHelper(root, i, j);
}
private int sumRangeHelper(SegmentTreeNode root, int start, int end){
if (root.end == end && root.start == start){
return root.sum;
}
else{
int mid = root.start + (root.end - root.start) / 2;
if (end <= mid){
return sumRangeHelper(root.left, start, end);
}
//make sure the boundary, we divide mid + 1 to right subtree.
else if (start >= mid + 1){
return sumRangeHelper(root.right, start, end);
}
else{
return sumRangeHelper(root.left, start, mid) + sumRangeHelper(root.right, mid + 1, end);
}
}
}
}
/**
* 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);
*/
construct: O(N)
update/search: O(logN)