0308. Range Sum Query 2D - Mutable
https://leetcode.com/problems/range-sum-query-2d-mutable
Description
Given a 2D matrix matrix, handle multiple queries of the following types:
Update the value of a cell in
matrix.Calculate the sum of the elements of
matrixinside the rectangle defined by its upper left corner(row1, col1)and lower right corner(row2, col2).
Implement the NumMatrix class:
NumMatrix(int[][] matrix)Initializes the object with the integer matrixmatrix.void update(int row, int col, int val)Updates the value ofmatrix[row][col]to beval.int sumRegion(int row1, int col1, int row2, int col2)Returns the sum of the elements ofmatrixinside the rectangle defined by its upper left corner(row1, col1)and lower right corner(row2, col2).
Example 1:

**Input**
["NumMatrix", "sumRegion", "update", "sumRegion"]
[[[[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]]], [2, 1, 4, 3], [3, 2, 2], [2, 1, 4, 3]]
**Output**
[null, 8, null, 10]
**Explanation**
NumMatrix numMatrix = new NumMatrix([[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]]);
numMatrix.sumRegion(2, 1, 4, 3); // return 8 (i.e. sum of the left red rectangle)
numMatrix.update(3, 2, 2); // matrix changes from left image to right image
numMatrix.sumRegion(2, 1, 4, 3); // return 10 (i.e. sum of the right red rectangle)Constraints:
m == matrix.lengthn == matrix[i].length1 <= m, n <= 200-105 <= matrix[i][j] <= 1050 <= row < m0 <= col < n-105 <= val <= 1050 <= row1 <= row2 < m0 <= col1 <= col2 < nAt most
104calls will be made tosumRegionandupdate.
ac1: plain pre-sum
Notice:
matrix cannot use
clone(), the array is Object, so it's shallow copybe careful handling first row, out of boundary exception.
class NumMatrix {
int[][] matrix, sumMatrix;
public NumMatrix(int[][] matrix) {
if(matrix == null || matrix.length == 0 || matrix[0].length == 0) return;
this.matrix = matrix;
int row = matrix.length;
int col = matrix[0].length;
this.sumMatrix = new int[row][col];
for(int c = 0; c < col; c++) {
sumMatrix[0][c] = matrix[0][c];
}
for (int r = 1; r < row; r++) {
for (int c = 0; c < col; c++) {
sumMatrix[r][c] = sumMatrix[r-1][c] + matrix[r][c];
}
}
}
public void update(int row, int col, int val) {
int diff = val - matrix[row][col];
matrix[row][col] = val;
for (int r = row; r < sumMatrix.length; r++) {
sumMatrix[r][col] += diff;
}
}
public int sumRegion(int row1, int col1, int row2, int col2) {
int sum = 0;
for (int c = col1; c <= col2; c++) {
if (row1 == 0) {
sum += sumMatrix[row2][c];
} else {
sum += sumMatrix[row2][c] - sumMatrix[row1-1][c];
}
}
return sum;
}
}
/**
* 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);
*/ac2: Binary Indexed Tree
class NumMatrix {
int[][] matrix, bit;
public NumMatrix(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return;
this.matrix = matrix;
int row = matrix.length;
int col = matrix[0].length;
bit = new int[row+1][col+1];
for (int r = 0; r < row; r++) {
for (int c = 0; c < col; c++) {
int val = matrix[r][c];
matrix[r][c] = 0;
update(r, c, val);
}
}
}
public void update(int row, int col, int val) {
int diff = val - matrix[row][col];
matrix[row][col] = val;
for (int r = row+1; r < bit.length; r += r & -r) {
for (int c = col+1; c < bit[0].length; c += c & -c) {
bit[r][c] += diff;
}
}
}
public int sumRegion(int row1, int col1, int row2, int col2) {
return getSum(row2, col2) - getSum(row1-1, col2) - getSum(row2, col1-1) + getSum(row1-1, col1-1);
}
private int getSum(int row, int col) {
int sum = 0;
for (int r = row+1; r > 0; r -= r & -r) {
for (int c = col+1; c > 0; c -= c & -c) {
sum += bit[r][c];
}
}
return sum;
}
}
/**
* 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);
*/
Last updated
Was this helpful?