动态区间和的两种解法(线段树和树状数组)
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;
}
}

浙公网安备 33010602011771号