LeetCode 307: Range Sum Query

/**
 * 307. Range Sum Query - Mutable
 * 1. Time:O(n)  Space:O(1)
 * 2. Time:O(logn)  Space:O(1)
 * 3. Time:O(logn)  Space:O(1)
 */

// 1. Time:O(n)  Space:O(1)
class NumArray {
    
    private int[] nums;

    public NumArray(int[] nums) {
        this.nums = nums;
    }
    
    public void update(int i, int val) {
        nums[i] = val;
    }
    
    public int sumRange(int i, int j) {
        int sum = 0;
        for(int cnt=i;cnt<=j;cnt++){
            sum += nums[cnt];
        }
        return sum;
    }
}

// 2. Time:O(logn)  Space:O(1)
class NumArray {
    
    private int[] tree;
    private int n;

    public NumArray(int[] nums) {
        n = nums.length;
        tree = new int[2*n];
        buildTree(nums);
    }
    
    // Time:O(n)  Space:O(n)
    private void buildTree(int[] nums){
        for(int i=n,j=0;i<2*n;i++,j++){
            tree[i] = nums[j];
        }
        for(int i=n-1;i>0;i--){
            tree[i] = tree[2*i] + tree[2*i+1];
        }
    }
    
    // Time:O(logn)  Space:O(1)
    public void update(int i, int val) {
        i += n;
        tree[i] = val;
        while(i>0){
            int left = i;
            int right = i;
            if(left%2!=0)
                left = i-1;
            else
                right = i+1;
            tree[i/2] = tree[left]+tree[right];
            i /= 2;
        }
    }
    
    // Time:O(logn)  Space:O(1)
    public int sumRange(int i, int j) {
        i += n;
        j += n;
        int sum = 0;
        while(i<=j){
            if(i%2==1){
                sum += tree[i];
                i++;
            }
            if(j%2==0){
                sum += tree[j];
                j--;
            }
            i /= 2;
            j /= 2;
        }
        return sum;
    }
}

// 3. Time:O(logn)  Space:O(1)
class NumArray {

    private Node root;
    
    public NumArray(int[] nums) {
        this.root = buildTree(nums,0,nums.length);
    }
    
    private Node buildTree(int[] nums, int begin, int end){
        if(nums==null || nums.length==0 || begin>=end)
            return null;
        if(begin == end-1)
            return new Node(begin,end,nums[begin]);
        Node cur = new Node(begin,end);
        int mid = begin+(end-begin)/2;
        cur.left = buildTree(nums,begin,mid);
        cur.right = buildTree(nums,mid,end);
        cur.sum = cur.left.sum + cur.right.sum;
        return cur;
    }
    
    public void update(int i, int val) {
        updateHelper(this.root,i,val);
    }
    
    private void updateHelper(Node root, int i, int val){
        if(root.begin==root.end-1 && root.begin==i){
            root.sum = val;
            return;
        }
        int mid = root.begin+(root.end-root.begin)/2;
        if(i<mid)
            updateHelper(root.left,i,val);
        else
            updateHelper(root.right,i,val);
        root.sum = root.left.sum + root.right.sum;
    }
    
    public int sumRange(int i, int j) {
        return sumRangeHelper(this.root,i,j+1);
    }
    
    private int sumRangeHelper(Node root,int i,int j){
        if(root==null || root.begin>=j || root.end<=i)
            return 0;
        if(root.begin>=i && root.end<=j)
            return root.sum;
        int mid = root.begin+(root.end-root.begin)/2;
        return sumRangeHelper(root.left,i,Math.min(mid,j))+sumRangeHelper(root.right,Math.max(mid,i),j);
    }
    
    private class Node{
        private int begin;
        private int end;
        private int sum;
        private Node left;
        private Node right;
        
        public Node(int begin,int end,int sum){
            this.begin = begin;
            this.end = end;
            this.sum = sum;
        }
        
        public Node(int begin,int end){
            this(begin,end,0);
        }
    }
}
原文地址:https://www.cnblogs.com/AAAmsl/p/12862420.html