segment tree

数组实现方式(类似与heap的实现方式):
class NumArray { int[] arr=null; int len = 0; public NumArray(int[] nums) { len = nums.length; arr = new int[len*10]; buildSegTree(nums,0,len-1,arr,0); } public void buildSegTree( int[] nums,int start,int end,int[] arr,int idx ){ if(start==end){ arr[idx] = nums[start]; return; } int mid = start+(end-start)/2; int left = idx*2+1; buildSegTree(nums,start,mid,arr,left); int right = idx*2+2; buildSegTree(nums,mid+1,end,arr,right); arr[idx] = arr[left]+arr[right]; // printTree(); } public void update(int index, int val) { // printTree(); updateSegTree(0,len-1,arr,0,index,val); // printTree(); } public void updateSegTree(int start,int end,int[] arr,int arrIdx,int index,int val){ if(index<start || index>end) return; if(start==end) arr[arrIdx]=val; else{ int mid = start+(end-start)/2; int left = arrIdx*2+1; updateSegTree(start,mid,arr,left,index,val); int right = arrIdx*2+2; updateSegTree(mid+1,end,arr,right,index,val); arr[arrIdx] = arr[left]+arr[right]; } } public int sumRange(int left, int right) { return sumSegTree(left,right,arr,0,len-1,0); } /** * l: 原始数组左边界 r: 原始数组右边界 arr: sum数组 start: 原始数组开始 end: 原始数组结束 idx: 当前节点 */ public int sumSegTree(int l,int r,int[] arr,int start,int end,int idx){ if(l>end || r<start) return 0; if(start==end) return arr[idx]; if( l<=start && end<=r ) return arr[idx]; int mid = start+(end-start)/2; return sumSegTree(l,r,arr,start,mid,idx*2+1) + sumSegTree(l,r,arr,mid+1,end,idx*2+2); } public void printTree(){ for(int num:arr) System.out.print(num+" "); System.out.println(); } } /** * Your NumArray object will be instantiated and called as such: * NumArray obj = new NumArray(nums); * obj.update(index,val); * int param_2 = obj.sumRange(left,right); */
TreeNode 实现方式(类似二叉树实现方式)
class NumArray { //定义SegmentTree 节点数据结构 class SegNode{ SegNode left; SegNode right; int sum; SegNode(SegNode left,SegNode right,int sum){ this.left = left; this.right = right; this.sum = sum; } } private SegNode root = null; private int len; public NumArray(int[] nums) { len = nums.length; root = buildSegTree(nums,0,len-1); } public SegNode buildSegTree(int[] nums,int start,int end){ if(start==end) return new SegNode(null,null,nums[start]); int mid = (start+end)/2; SegNode left = buildSegTree(nums,start,mid); SegNode right = buildSegTree(nums,mid+1,end); return new SegNode(left,right,left.sum+right.sum); } public void update(int index, int val) { updateSegNode(root,0,len-1,index,val); } public void updateSegNode(SegNode root,int start,int end,int index,int val){ if(start>index||end<index) return ; if(start==end){ root.sum = val; return; } int mid = (start+end)/2; updateSegNode(root.left, start,mid,index,val); updateSegNode(root.right,mid+1,end,index,val); root.sum = root.left.sum+root.right.sum; } public int sumRange(int left, int right) { return getSegSum(root,0,len-1,left,right); } public int getSegSum(SegNode root,int start,int end,int left,int right){ if(start>right || end<left) return 0; if(start==end) return root.sum; if(left<start && end<right) return root.sum; int mid = (start+end)/2; return getSegSum(root.left, start,mid,left,right) + getSegSum(root.right,mid+1,end,left,right); } } /** * Your NumArray object will be instantiated and called as such: * NumArray obj = new NumArray(nums); * obj.update(index,val); * int param_2 = obj.sumRange(left,right); */

浙公网安备 33010602011771号