您的位置:首页 > 产品设计 > UI/UE

307. Range Sum Query - Mutable

2016-02-02 17:01 435 查看
题目:

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.

传统做法:

We have an array arr[0 . . . n-1]. We should be able to
1 Find the sum of first i elements.
2 Change value of a specified element of the array arr[i] = x where 0 <= i <= n-1.

A simple solution is to run a loop from 0 to i-1 and calculate sum of elements. To update a value, simply do arr[i] = x. The first operation takes
O(n) time and second operation takes O(1) time. Another simple solution is to create another array and store sum from start to i at the i’th index in this array. Sum of a given range can now be calculated in O(1) time, but update operation takes O(n) time
now. This works well if the number of query operations are large and very few updates.

这种数组经常要update的,就需要用segment tree,可参考:
https://www.youtube.com/watch?v=ZBHKZF5w4YU http://www.geeksforgeeks.org/segment-tree-set-1-sum-of-given-range/


<span style="font-size:14px;">public class NumArray {

class segmentTreeNode {
int start, end;
segmentTreeNode left, right;
int sum;
public segmentTreeNode(int start, int end) {
this.start=start;
this.end=end;
this.left=null;
this.right=null;
this.sum=0;
}
}

segmentTreeNode root=null;

public NumArray(int[] nums) {
root=buildTree(nums,0,nums.length-1);
}

public 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;
}
}

void update(int i, int val) {
update(root,i,val);
}

void update(segmentTreeNode root, int i, int val) {
if(root.start==root.end) {
root.sum=val;
} else {
int mid=root.start+(root.end-root.start)/2;
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);
}

public int sumRange(segmentTreeNode root, int i, int j) {
if(root.start==i&&root.end==j) {
return root.sum;
} else {
int mid=root.start+(root.end-root.start)/2;
if(mid>=j) {
return sumRange(root.left,i,j);
} else if(mid+1<=i) {
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 numArray = new NumArray(nums);
// numArray.sumRange(0, 1);
// numArray.update(1, 10);
// numArray.sumRange(1, 2);</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode