Range Sum Query
来源:互联网 发布:童声配音软件 编辑:程序博客网 时间:2024/04/19 11:46
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) -> 9update(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.
可以看看这个链接,关于线段树,写的挺好的。
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); */
阅读全文
0 0
- Range Sum Query - Immutable
- Range Sum Query - Immutable
- Range Sum Query - Immutable
- Range Sum Query - Immutable
- Range Sum Query - Immutable
- [Leetcode]Range Sum Query
- Range Sum Query - Immutable
- Range Sum Query - Immutable
- 303,Range Sum Query
- Range Sum Query - Immutable
- Range Sum Query - Immutable
- Range Sum Query - Mutable
- Range Sum Query - Immutable
- Range Sum Query - Immutable
- Range Sum Query - Javacript
- Range Sum Query - Immutable
- Range Sum Query - Mutable
- Range Sum Query - Immutable
- SpringBoot学习——No.2
- chkconfig安装包和安装命令。free
- float数据在内存中的存储方法
- easy ui 表格格式化动态绑定,表格格式化后获取表格值是value而不是显示的值
- java 实现的simhash中文指纹项目
- Range Sum Query
- Python进阶三部曲网络编程.md
- 前台js解析json数据
- kernel解析设备树生成设备节点过程
- Glide-更多图片变换,glide-transformations的使用(六)
- 包
- 密码加密的最好方式
- 1111111
- 读《1984》小说