304. Range Sum Query 2D - Immutable
by Botao Xiao
304. Range Sum Query 2D - Immutable
Question:
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).
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:
- You may assume that the matrix does not change.
- There are many calls to sumRegion function.
- You may assume that row1 ≤ row2 and col1 ≤ col2.
Thinking:
- Method 1:
- 参考303. Range Sum Query - Immutable
- 将每一行都类似303储存,当要计算矩阵的和时,我们对于每一行都按照303的计算方法,最后算和。
class NumMatrix {
private int[][] dp;
public NumMatrix(int[][] matrix) {
if(matrix == null || matrix.length == 0 || matrix[0].length == 0) return;
int height = matrix.length, width = matrix[0].length;
dp = new int[height][width + 1];
for(int i = 0; i < height; i++)
dp[i][0] = 0;
for(int i = 0; i < height; i++)
for(int j = 0; j < width; j++)
dp[i][j + 1] = dp[i][j] + matrix[i][j];
}
public int sumRegion(int row1, int col1, int row2, int col2) {
int sum = 0;
for(; row1 <= row2; row1++)
sum += this.dp[row1][col2 + 1] - dp[row1][col1];
return sum;
}
}
/**
* Your NumMatrix object will be instantiated and called as such:
* NumMatrix obj = new NumMatrix(matrix);
* int param_1 = obj.sumRegion(row1,col1,row2,col2);
*/
- Method 2:
- 仍然是dp,但是每个位置都存储从matrix[0][0]加到当前的值。
- dp[a][b] = dp[a - 1][b] + dp[a][b - 1] - dp[a - 1][b - 1] (若果存在的话)
- 第一行和第一列的值递加。
- 查找时
- 减去左下角左边的值,减去右上角上面的值,再加上左上角的左上角的值。
- 仍然是dp,但是每个位置都存储从matrix[0][0]加到当前的值。
class NumMatrix {
private int[][] dp;
public NumMatrix(int[][] matrix) {
if(matrix == null || matrix.length == 0 || matrix[0].length == 0) return;
int height = matrix.length, width = matrix[0].length;
dp = new int[height][width];dp[0][0] = matrix[0][0];
for(int i = 1; i < width; i++)
dp[0][i] = dp[0][i - 1] + matrix[0][i];
for(int i = 1; i < height; i++)
dp[i][0] = dp[i - 1][0] + matrix[i][0];
for(int i = 1; i < height; i++){
for(int j = 1; j < width; j++){
dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1] + matrix[i][j];
}
}
}
public int sumRegion(int row1, int col1, int row2, int col2) {
int result = dp[row2][col2];
if(col1 > 0)
result -= dp[row2][col1 - 1];
if(row1 > 0)
result -= dp[row1 - 1][col2];
if(row1 > 0 && col1 > 0)
result += dp[row1 - 1][col1 - 1];
return result;
}
}
/**
* Your NumMatrix object will be instantiated and called as such:
* NumMatrix obj = new NumMatrix(matrix);
* int param_1 = obj.sumRegion(row1,col1,row2,col2);
*/
Second time
- Use a 2-D array to save the rectangle sum from (0, 0) to current point.
class NumMatrix { private int[][] dp; public NumMatrix(int[][] matrix) { if(matrix == null || matrix.length == 0 || matrix[0].length == 0){ dp = new int[0][0]; return; } int height = matrix.length, width = matrix[0].length; dp = new int[height][width]; for(int i = 0; i < height; i++){ for(int j = 0; j < width; j++){ int cur = 0; for(int p = 0; p <= i; p++){ cur += matrix[p][j]; } dp[i][j] = (j > 0 ? dp[i][j - 1]: 0) + cur; } } } public int sumRegion(int row1, int col1, int row2, int col2) { return dp[row2][col2] - (col1 > 0 ? dp[row2][col1 - 1]: 0) - (row1 > 0 ? dp[row1 - 1][col2]: 0) + (col1 > 0 && row1 > 0 ? dp[row1 - 1][col1 - 1]: 0); } } /** * Your NumMatrix object will be instantiated and called as such: * NumMatrix obj = new NumMatrix(matrix); * int param_1 = obj.sumRegion(row1,col1,row2,col2); */
Subscribe via RSS