Interval Sum II

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

  • For query(start, end), return the sum from index start to index end in the given array.

  • For modify(index, value), modify the number in the given index to value

Example:

Given array A = [1,2,7,8,5].

query(0, 2), return 10.
modify(0, 4), change A[0] from 1 to 4.
query(0, 1), return 6.
modify(2, 1), change A[2] from 7 to 1.
query(2, 4), return 14.

Solution:

This problem can be easily solved by Segment Tree.

Code:

public class Solution {
    class SegmentNode {
        int start;
        int end;
        long sum;
        SegmentNode left;
        SegmentNode right;
        public SegmentNode(int start, int end) {
            this.start = start;
            this.end = end;
            this.sum = 0;
        }
    }

    private SegmentNode root;

    public Solution(int[] A) {
        if (A == null || A.length == 0) {
            root = null;
        } else {
            root = buildTree(A);
            for (int i = 0; i < A.length; i++) {
                modify(i, A[i]);
            }
        }

    }

    private SegmentNode buildTree(int[] A) {
        Stack<SegmentNode> stack = new Stack<>();
        SegmentNode root = new SegmentNode(0, A.length - 1);
        stack.push(root);
        while (!stack.empty()) {
            SegmentNode node = stack.pop();
            if (node.start == node.end) {
                continue;
            }
            int mid = node.start + (node.end - node.start) / 2;
            if (node.start <= mid) {
                node.left = new SegmentNode(node.start, mid);
                stack.push(node.left);
            } 
            if (mid + 1 <= node.end) {
                node.right = new SegmentNode(mid + 1, node.end);
                stack.push(node.right);
            }
        }
        return root;
    }

    /**
     * @param start, end: Indices
     * @return: The sum from start to end
     */
    public long query(int start, int end) {
        return queryHelper(root, start, end);
    }

    private long queryHelper(SegmentNode node, int start, int end) {
        if (node == null || start > end) {
            return 0L;
        }
        if (start <= node.start && node.end <= end) {
            return node.sum;
        }
        long sum = 0;
        int mid = node.start + (node.end - node.start) / 2;
        if (start <= mid) {
            if (mid < end) {
                sum += queryHelper(node.left, start, mid);
            } else {
                sum += queryHelper(node.left, start, end);
            }
        }
        if (mid < end) {
            if (start <= mid) {
                sum += queryHelper(node.right, mid + 1, end);
            } else {
                sum += queryHelper(node.right, start, end);
            }
        }
        return sum;
    }

    /**
     * @param index, value: modify A[index] to value.
     */
    public void modify(int index, int value) {
        modifyHelper(root, index, value);
    }

    private void modifyHelper(SegmentNode node, int index, int value) {
        if (node == null) {
            return;
        }
        if (node.start == index && node.end == index) {
            node.sum = value;
            return;
        }
        int mid = node.start + (node.end - node.start) / 2;
        if (index <= mid) {
            modifyHelper(node.left, index, value);
        } else {
            modifyHelper(node.right, index, value);
        }
        if (node.left != null) {
            node.sum = node.left.sum;
        }
        if (node.right != null) {
            node.sum += node.right.sum;
        }
    }
}

results matching ""

    No results matching ""