AdSense

Tuesday, June 28, 2016

Range Sum Query 2D - Immutable

Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper left corner (row1, col1) and lower right corner (row2, col2).
Range Sum Query 2D
The above rectangle (with the red border) is defined by (row1, col1) = (2, 1) and (row2, col2) = (4, 3), which contains sum = 8.
Example:
Given matrix = [
  [3, 0, 1, 4, 2],
  [5, 6, 3, 2, 1],
  [1, 2, 0, 1, 5],
  [4, 1, 0, 1, 7],
  [1, 0, 3, 0, 5]
]

sumRegion(2, 1, 4, 3) -> 8
sumRegion(1, 1, 2, 2) -> 11
sumRegion(1, 2, 2, 4) -> 12
Note:
  1. You may assume that the matrix does not change.
  2. There are many calls to sumRegion function.
  3. You may assume that row1 ≤ row2 and col1 ≤ col2.

This question is not as easy as it looks like: the time limit will exceed if you just sum up everything when calling the function. A smarter way is to initialize a helper matrix in that each element (x, y) is the sum of matrix from (0, 0) to (x, y). Then whenever we need to call the function, we subtract from the helper matrix to get the answer.


public class NumMatrix {
    private int[][] sumMatrix;
    public NumMatrix(int[][] matrix) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
            sumMatrix = null;
        } else {
            sumMatrix = new int[matrix.length][matrix[0].length];
            for (int i = 0; i < matrix.length; i++) {
                sumMatrix[i][0] = matrix[i][0];
            }
            for (int i = 0; i < matrix.length; i++) {
                for (int j = 1; j < matrix[0].length; j++) {
                sumMatrix[i][j] = sumMatrix[i][j - 1] + matrix[i][j];
                }
            }
        
            for (int i = 1; i < matrix.length; i++) {
                for (int j = 0; j < matrix[0].length; j++) {
                    sumMatrix[i][j] += sumMatrix[i - 1][j]; 
                }
            }
        }
        
    }

    public int sumRegion(int row1, int col1, int row2, int col2) {
        if (sumMatrix == null)
            return 0;
        if (row1 == 0 && col1 == 0) {
            return sumMatrix[row2][col2];
        } else if (row1 == 0) {
            return sumMatrix[row2][col2] - sumMatrix[row2][col1 - 1];
        } else if (col1 == 0) {
            return sumMatrix[row2][col2] - sumMatrix[row1 - 1][col2];
        } else {
            return sumMatrix[row2][col2] - sumMatrix[row1 - 1][col2] - sumMatrix[row2][col1 - 1] 
            + sumMatrix[row1 - 1][col1 - 1];
        }
    }
}


No comments:

Post a Comment