Range Query, Immutable and Mutable


Range Sum Query - Immutable

Immutable求sum,要想到prifixSum。

public class NumArray {

    int[] prefixSum;

    public NumArray(int[] nums) {
        int n = nums.length;
        prefixSum = new int[n + 1];

        int sum = 0;
        for (int i = 1; i <= n; i++) {
            sum += nums[i - 1];
            prefixSum[i] = sum;
        }
    }

    public int sumRange(int i, int j) {
        return prefixSum[j + 1] - prefixSum[i];
    }
}

Range Sum Query 2D - Immutable

public class NumMatrix {

    int[][] dp;

    public NumMatrix(int[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0) {
            return;
        }

        int m = matrix.length, n = matrix[0].length;
        dp = new int[m + 1][n + 1];

        int sum = 0;
        for (int i = 1; i <= m; i++) {
            sum += matrix[i - 1][0];
            dp[i][1] = sum;
        }

        sum = 0;
        for (int j = 1; j <= n; j++) {
            sum += matrix[0][j - 1];
            dp[1][j] = sum;
        }

        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                dp[i][j] = dp[i][j - 1] + dp[i - 1][j] - dp[i - 1][j - 1] + matrix[i - 1][j - 1];
            }
        }
    }

    public int sumRegion(int row1, int col1, int row2, int col2) {
        if (dp == null) {
            return 0;
        }

        int smallRow = Math.min(row1, row2);
        int bigRow = Math.max(row1, row2);
        int smallCol = Math.min(col1, col2);
        int bigCol = Math.max(col1, col2);

        return dp[bigRow + 1][bigCol + 1] - dp[bigRow + 1][smallCol] - dp[smallRow][bigCol + 1] + dp[smallRow][smallCol];
    }
}

/**
 * Your NumMatrix object will be instantiated and called as such:
 * NumMatrix obj = new NumMatrix(matrix);
 * int param_1 = obj.sumRegion(row1,col1,row2,col2);
 */

Range Sum Query - Mutable

Mutable且一维时,segment tree是个选择。

public class NumArray {

    SegmentTreeNode root;

    public NumArray(int[] nums) {
        if (nums == null || nums.length == 0) {
            return;
        }

        root = build(nums, 0, nums.length - 1);
    }

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

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

    private int query(SegmentTreeNode root, int start, int end) {
        if (start <= root.start && end >= root.end) {
            return root.sum;
        } 

        int mid = root.start + (root.end - root.start) / 2;
        if (mid >= end) {
            return query(root.left, start, end);
        } else if (mid + 1 <= start) {
            return query(root.right, start, end);
        }

        int left = query(root.left, start, mid);
        int right = query(root.right, mid + 1, end);
        return left + right;
    }

    private SegmentTreeNode modify(SegmentTreeNode root, int i, int val) {
        if (root == null || i < root.start || i > root.end) {
            return root;
        } else if (root.start == i && root.end == i) {
            root.sum = val;
            return root;
        }

        SegmentTreeNode left = modify(root.left, i, val);
        SegmentTreeNode right = modify(root.right, i, val);
        root.sum = left.sum + right.sum;
        return root;
    }

    private SegmentTreeNode build(int[] nums, int start, int end) {
        if (start > end) {
            return null;
        }

        SegmentTreeNode root = new SegmentTreeNode(start, end, nums[start]);
        if (start < end) {
            int mid = start + (end - start) / 2;
            root.left = build(nums, start, mid);
            root.right = build(nums, mid + 1, end);
            root.sum = root.left.sum + root.right.sum;
        }
        return root;
    }
}

class SegmentTreeNode {
    int start, end, sum;
    SegmentTreeNode left, right;

    public SegmentTreeNode(int start, int end, int sum) {
        this.start = start;
        this.end = end;
        this.sum = sum;
    }
}

/**
 * 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);
 */

results matching ""

    No results matching ""