LeetCode - 307. Range Sum Query - Mutable

Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive.

The update(i, val) function modifies nums by updating the element at index i to val.

Example:

Given nums = [1, 3, 5]

sumRange(0, 2) -> 9
update(1, 2)
sumRange(0, 2) -> 8

 

Note:

  1. The array is only modifiable by the update function.
  2. You may assume the number of calls to update and sumRange function is distributed evenly.

利用线段树解决动态区间求值问题、

class NumArray {

    class STreeNode {
        int sum;
        int start;
        int end;
        STreeNode left, right;
        STreeNode(int start, int end) {
            this.start = start;
            this.end = end;
            this.sum = 0;
        }
    }

    private STreeNode buildSTree(int[] nums, int start, int end) {
        if (start > end)
            return null;
        else {
            STreeNode node = new STreeNode(start, end);
            if (start == end) {
                node.sum = nums[start];
            }
            else {
                int mid = start + (end - start) / 2;
                node.left = buildSTree(nums, start, mid);
                node.right = buildSTree(nums, mid+1, end);
                if (node.left != null && node.right != null)
                    node.sum = node.left.sum + node.right.sum;
            }
            return node;
        }
    }

    private STreeNode root;
    public NumArray(int[] nums) {
        root = buildSTree(nums, 0, nums.length-1);
    }

    public void update(int i, int val) {
        update(root, i, val);
    }

    private void update(STreeNode node, int pos, int val) {
        // if (node == null)
        //     return;
        if (node.start == pos && node.end == pos) {
            node.sum = val;
            return;
        }
        if (node.left != null && node.right != null) {
            int mid = node.start + (node.end - node.start) / 2;
            if (pos <= mid)
                update(node.left, pos, val);
            else
                update(node.right, pos, val);
        
            node.sum = node.left.sum + node.right.sum;
        }
        
    }

    public int sumRange(int i, int j) {
        return sumRange(root, i, j);
    }

    private int sumRange(STreeNode node, int i, int j) {
        if (node == null)
            return 0;
        if (node.start == i && node.end == j)
            return node.sum;
        int mid = node.start + (node.end - node.start) / 2;
        if (j <= mid)
            return sumRange(node.left, i, j);
        else if (i > mid)
            return sumRange(node.right, i, j);
        else
            return sumRange(node.left, i, mid) + sumRange(node.right, mid+1, j);
    }

}

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray obj = new NumArray(nums);
 * obj.update(i,val);
 * int param_2 = obj.sumRange(i,j);
 */

 

posted @ 2017-08-23 13:44  Pickle  阅读(173)  评论(0编辑  收藏  举报