动态区间和的两种解法(线段树和树状数组)
307. Range Sum Query - Mutable 求两下标区间之间的和。
1. 利用树状数组来求解(https://www.cnblogs.com/hsd-/p/6139376.html)。
class NumArray { int[] tree; int[] array; int len; public int lowbit(int n){ return n&(-n); } public int getSum(int n){ int sum=0; for(int k=n;k>0;k=k-lowbit(k)){ sum+=tree[k]; } return sum; } public NumArray(int[] nums) { len=nums.length; tree=new int[len+1]; array=new int[len]; for(int i=0;i<len;i++){ array[i]=nums[i]; for(int j=i+1;j<=len;j=j+lowbit(j)){ tree[j]+=nums[i]; } } } public void update(int i, int val) { int addNum=val-array[i]; for(int k=i+1;k<=len;k+=lowbit(k)){ tree[k]+=addNum; } array[i]=val; } public int sumRange(int i, int j) { return getSum(j+1)-getSum(i); } }
2.利用线段树求解
class NumArray { SegmentNode root; public NumArray(int[] nums) { root=buildNode(nums,0,nums.length-1); } public void update(int i, int val) { updateNode(root,i,val); } public int sumRange(int i, int j) { return sumNode(root,i,j); } public SegmentNode buildNode(int[] nums,int start,int end){ if(start<end){ return null; } SegmentNode node=new SegmentNode(start,end); if(start==end){ node.sum=nums[start]; return node; } int mid=(start+end)/2; node.left=buildNode(nums,start,mid); node.right=buildNode(nums,mid+1,end); node.sum=node.left.sum+node.right.sum; return node; } public void updateNode(SegmentNode node,int index,int value){ if(node.start==node.end && node.start==index){ node.sum=value; return; } if(index<node.start || index>node.end){ return; } int mid=(node.start+node.end)/2; if(index<=mid){ updateNode(node.left,index,value); }else{ updateNode(node.right,index,value); } node.sum=node.left.sum+node.right.sum; } public int sumNode(SegmentNode node,int left,int right){ if(node.start==left && node.end==right){ return node.sum; } int mid=(node.start+node.end)/2; if(right<=mid){ return sumNode(node.left,left,right); }else if(left>mid){ return sumNode(node.right,left,right); }else{ return sumNode(node.left,left,mid)+sumNode(node.right,mid+1,right); } } } class SegmentNode{ int start; int end; int sum; SegmentNode left; SegmentNode right; SegmentNode(int start,int end){ this.start=start; this.end=end; this.sum=0; } }