Interval Sum II

Given an integer array in the construct method, implement two methods query(start, end) and modify(index, value):

  • For query(startend), return the sum from index start to index end in the given array.
  • For modify(indexvalue), modify the number in the given index to value

Example

Example 1

Input:
[1,2,7,8,5]
[query(0,2),modify(0,4),query(0,1),modify(2,1),query(2,4)]
Output: [10,6,14]
Explanation:
Given array A = [1,2,7,8,5].
After query(0, 2), 1 + 2 + 7 = 10,
After modify(0, 4), change A[0] from 1 to 4, A = [4,2,7,8,5].
After query(0, 1), 4 + 2 = 6.
After modify(2, 1), change A[2] from 7 to 1,A = [4,2,1,8,5].
After query(2, 4), 1 + 8 + 5 = 14.

Example 2

Input:
[1,2,3,4,5]
[query(0,0),query(1,2),quert(3,4)]
Output: [1,5,9]
Explantion:
1 = 1
2 + 3 = 5
4 + 5 = 9

Challenge

O(logN) time for query and modify.

Notice

We suggest you finish problem Segment Tree BuildSegment Tree Query and Segment Tree Modify first.

思路:这题典型的segment tree或者树状数组的解法;只有这样才能做到 O(logN)的query和modify操作;

public class Solution {
    /* you may need to use some attributes here */

    /*
    * @param A: An integer array
    */
    private SegmentTree tree;
    public Solution(int[] A) {
        tree = new SegmentTree(A);
    }

    /*
     * @param start: An integer
     * @param end: An integer
     * @return: The sum from start to end
     */
    public long query(int start, int end) {
        return tree.querySum(start, end);
    }

    /*
     * @param index: An integer
     * @param value: An integer
     * @return: nothing
     */
    public void modify(int index, int value) {
        tree.modify(index, value);
    }
    
    private class SegmentTreeNode {
        public int start, end;
        public long sum;
        public SegmentTreeNode left, right;
        public SegmentTreeNode(int start, int end) {
            this.start = start;
            this.end = end;
            this.sum = 0;
            this.left = null;
            this.right = null;
        }
    }
    
    private class SegmentTree {
        private SegmentTreeNode root;
        private int size;
        
        public SegmentTree(int[] A) {
            this.size = A.length;
            this.root = buildTree(A, 0, size - 1);
        }
        
        private SegmentTreeNode buildTree(int[] A, int start, int end) {
            if(start > end) {
                return null;
            }
            SegmentTreeNode node = new SegmentTreeNode(start, end);
            if(start == end) {
                node.sum = A[start];
                return node;
            }
            int mid = start + (end - start) / 2;
            node.left = buildTree(A, start, mid);
            node.right = buildTree(A, mid + 1, end);
            node.sum = node.left.sum + node.right.sum;
            return node;
        }
        
        private long querySum(SegmentTreeNode root, int start, int end) {
            if(root.start == start && root.end == end) {
                return root.sum;
            }
            int mid = root.start + (root.end - root.start) / 2;
            long leftsum = 0, rightsum = 0;
            if(start <= mid) {
                leftsum = querySum(root.left, start, Math.min(mid, end));
            }
            if(end >= mid + 1) {
                rightsum = querySum(root.right, Math.max(start, mid + 1), end);
            }
            return leftsum + rightsum;
        }
        
        private void modify(SegmentTreeNode root, int index, int value) {
            if(root.start == root.end && root.end == index) {
                root.sum = value;
                return;
            }
            int mid = root.start + (root.end - root.start) / 2;
            if(index <= mid) {
                modify(root.left, index, value);
            } else {
                modify(root.right, index, value);
            }
            root.sum = root.left.sum + root.right.sum;
        }
        
        public long querySum(int start, int end) {
            return querySum(root, start, end);
        }
        
        public void modify(int index, int value) {
            modify(root, index, value);
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值