1. 程式人生 > 其它 >307. 區域和檢索-陣列不可變

307. 區域和檢索-陣列不可變

class NumArray {

    SegmentTree segmentTree;

    public NumArray(int[] nums) {

        segmentTree = new SegmentTree(nums);
    }

    public void update(int index, int val) {

        segmentTree.update(index, val);
    }

    public int sumRange(int left, int right) {

        return segmentTree.sumRange(left, right);
    }
}

/**
 * 使用線段樹對區間求和,更新區間值
 */
 class SegmentTree {

    int[] data;
    int[] tree;

    public SegmentTree(int[] arr){

        data = arr;
        tree = new int[data.length * 4];

        buildSegmentTree(0, 0, data.length - 1);
    }

    public void buildSegmentTree(int treeIndex, int left, int right){

        if (left == right){

            tree[treeIndex] = data[left];
            return;
        }

        int mid = left + (right - left) / 2;

        buildSegmentTree(leftChild(treeIndex), left, mid);
        buildSegmentTree(rightChild(treeIndex), mid + 1, right);

        tree[treeIndex] = tree[leftChild(treeIndex)] + tree[rightChild(treeIndex)];
    }

    public void update(int index, int val){

        data[index] = val;
        update(0, 0, data.length - 1, index, val);
    }

    private void update(int treeIndex, int left, int right, int index, int val){

        if (left == right){

            tree[treeIndex] = val;
            return;
        }

        int mid = left + (right - left)/ 2;

        if (index >= mid + 1){
            update(rightChild(treeIndex), mid + 1, right, index, val);
        }
        else {
            update(leftChild(treeIndex), left, mid, index, val);
        }

        tree[treeIndex] = tree[leftChild(treeIndex)] + tree[rightChild(treeIndex)];
    }

    public int sumRange(int left, int right){

        return sumRange(0, 0, data.length - 1, left, right);
    }

    private int sumRange(int treeIndex, int l, int r, int left, int right){

        if (l == left && r == right){

            return tree[treeIndex];
        }

        int mid = l + (r - l) / 2;

        if (left >= mid + 1){
            return sumRange(rightChild(treeIndex), mid + 1, r, left, right);
        }
        else if (right <= mid){
            return sumRange(leftChild(treeIndex), l, mid, left, right);
        }
        else {

            int resLeft = sumRange(leftChild(treeIndex), l, mid, left, mid);
            int resRight = sumRange(rightChild(treeIndex), mid + 1, r, mid + 1, right);

            return resLeft + resRight;
        }
    }

    public int leftChild(int index){

        return 2 * index + 1;
    }

    public int rightChild(int index){

        return 2 * index + 2;
    }
 }

https://leetcode-cn.com/problems/range-sum-query-mutable/