动态区间和的两种解法(线段树和树状数组)

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;
    }
}

  

posted @ 2018-03-16 17:11  xinyilovestudy  阅读(143)  评论(0编辑  收藏  举报