Monday, November 12, 2018

308. Range Sum Query 2D - Mutable

308Range Sum Query 2D - Mutable
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
update(3, 2, 2)
sumRegion(2, 1, 4, 3) -> 10
Note:
  1. The matrix is only modifiable by the update function.
  2. You may assume the number of calls to update and sumRegion function is distributed evenly.
  3. You may assume that row1 ≤ row2 and col1 ≤ col2.
----------------------------------------------
需要与面试官沟通 
read heavy - 那就正常写,矩阵里面直接存cumulative sum. 读是O(1), 写是O(m * n)

write heavy -  bit, 读写都是O(log m * log n)

Solution #1 Binary index tree,
class NumMatrix {

    private int[][] bit;
    private int[][] matrix;
    private int m;
    private int n;
    public NumMatrix(int[][] matrix) {
        if (matrix.length == 0 || matrix[0].length == 0) return;
        m = matrix.length;
        n = matrix[0].length;
        bit= new int[m + 1][n + 1];
        this.matrix = new int[m][n];
        initBit(matrix);
    }
    
    private void initBit(int[][] matrix) {
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                update(i, j, matrix[i][j]);
            }
        }
        
    } 
    
    public void update(int row, int col, int val) {
        if (m == 0 || n == 0) return;
        int delta = val - matrix[row][col];
        matrix[row][col] = val;
        row++;
        col++;
        
        while (row <= m) {
            updateY(row, col, delta);
            row += (row & -row);
        }
    }
    
    public void updateY(int row, int col, int val) {
        while (col <= n) {
            bit[row][col] += val;
            col += (col & -col);   
        }
    }
    
    public int sumRegion(int row1, int col1, int row2, int col2) {
        if (m == 0 || n == 0) return 0;
        return read(row2, col2) - read(row2, col1 - 1) - read(row1 - 1, col2) + read(row1 - 1, col1 - 1);
    }
    
    public int read(int row, int col) {
        row++;
        col++;
        int rt = 0;
        
        while (row > 0) {
            rt += readY(row, col);
            row -= (row & -row);
        }
        
        return rt;
    }
    
    public int readY(int row, int col) {
        int rt = 0;
        while (col > 0) {
            rt += bit[row][col];
            col -= (col & -col);
        }
        
        return rt;
    }
}

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

No comments:

Post a Comment