Range Sum Query - Mutable:对区域内的值经常改变的数组求区域内的和 线段数
2017-11-06 10:25
323 查看
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:
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.
思路一:因为区域内的值经常改变,朴素的直接查找范围需要O(n),会超时,因此考虑线段树
可以看看这个链接,关于线段树,写的挺好的。
https://leetcode.com/problems/range-sum-query-mutable/solution/
时空复杂度:
预处理:O(n) O(N)
查询:O(logN) O(1)
更新:O(logN) O(1)
就是预先划分出若干部分,提前算好和,加快速度
时空复杂度:
预处理:O(n) O(sqrt(N))
查询:O(sqrt(N)) O(1)
更新: O(1) O(1)
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.
思路一:因为区域内的值经常改变,朴素的直接查找范围需要O(n),会超时,因此考虑线段树
可以看看这个链接,关于线段树,写的挺好的。
https://leetcode.com/problems/range-sum-query-mutable/solution/
时空复杂度:
预处理:O(n) O(N)
查询:O(logN) O(1)
更新:O(logN) O(1)
class NumArray { int[] segtree; int n; //int[] lazy; public NumArray(int[] nums) { n = nums.length; segtree = new int[2*nums.length]; buildTree(nums); } public void buildTree(int[] nums){ //构建线段树,其父节点包含两个子节点区域的求和信息 //存储时segtree[]中 n到2n-1存储的叶子节点(nums数组),1-n-1存储的中间节点(区域信息),0位置未使用 for(int i = n,j = 0;i<2*n&&j<n;i++,j++){ segtree[i] = nums[j]; } for(int i =n-1;i>0;i--){ segtree[i] = segtree[2*i] + segtree[2*i+1]; } } public void update(int i, int val) { int pos = i+n; segtree[pos] = val; while(pos>0){ int left = pos; int right = pos; if(pos%2==0)//因为构建树时,i = i*2 + i*2+1,所以左孩子为2*n为偶数,右孩子为2*n+1为奇数 { right = pos+1; }else{ left = pos -1; } segtree[pos/2] = segtree[left] + segtree[right]; pos = pos/2; } } public int sumRange(int i, int j) { int left = i+n; int right = j+n; int result = 0; while(left<=right){//范围未重合,等号表示父节点刚好表示左右的范围 if(left%2==1)//左边界是父节点的右孩子,那么其父节点的范围过大,所以不必将父节点累加,只需将其单独累加进结果,并缩小范围 { result += segtree[left]; left++; } if(right%2==0)//右边界是父节点的左孩子,那么父节点的范围超出了查询范围,所以不考虑其父节点,单独将右边界的结果加入结果中 { result += segtree[right]; right--; } left /= 2;//查询值其父节点,因为构建树时父节点包含了区域信息 right /=2; } return result; } } /** * 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); */思路二:
(Sqrt decomposition)
就是预先划分出若干部分,提前算好和,加快速度时空复杂度:
预处理:O(n) O(sqrt(N))
查询:O(sqrt(N)) O(1)
更新: O(1) O(1)
class NumArray { //分而治之,没sqrt(n)为一块,预先统计出每一块的总和,加快速度 int[] block; int len; int[] num; public NumArray(int[] nums) { double l =Math.sqrt(nums.length);//计算每段的长度 len =(int)Math.ceil(nums.length/l);//九三一共需要的段数,需要向上取证,因为要包括所有的元素 block = new int[nums.length]; num = nums; for(int i = 0;i<nums.length;i++){ block[i/len] += nums[i]; } } public void update(int i, int val) { block[i/len] = block[i/len] + val - num[i]; num[i] = val; } public int sumRange(int i, int j) { int result = 0; int lblock = i/len; int rblock = j/len; if(lblock == rblock){ for(int a = i;a<=j;a++){ result += num[a]; } return result; }else{ for(int a = i;a<=(lblock+1)*len-1;a++){ result += num[a]; } for(int a = lblock+1;a<rblock;a++){ result += block[a]; } for(int a = rblock*len;a<=j;a++){ result += num[a]; } return result; } } } /** * 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); */
相关文章推荐
- LeetCode 307 Range Sum Query - Mutable(树状数组)
- (LeetCode 307) Range Sum Query - Mutable(树状数组讲解)
- LeetCode 307 Range Sum Query - Mutable(树状数组 || 线段树)
- leetcode 307. Range Sum Query - Mutable(树状数组)
- [LeetCode] Range Sum Query 2D - Mutable 二维区域和检索 - 可变
- [LeetCode] Range Sum Query - Mutable 区域和检索 - 可变
- LeetCode[307]Range Sum Query - Mutable(Java)
- [LeetCode] Range Sum Query - Mutable
- LeetCode-Range Sum Query - Mutable
- Range Sum Query - Mutable
- leetcode - Range Sum Query - Mutable
- 303. Range Sum Query - Immutable && 304. Range Sum Query 2D - Immutable && 307. Range Sum Query - Mutable && 308. Range Sum Query 2D - Mutable
- 307. Range Sum Query - Mutable
- leetcode之Range Sum Query - Mutable
- [leetcode] 307. Range Sum Query - Mutable 解题报告
- Range Sum Query - Mutable -leetcode
- LeetCode(307) Range Sum Query - Mutable
- Leetcode: Range Sum Query - Mutable
- leetcode Range Sum Query-Mutable
- LeetCode() Range Sum Query-mutable