您的位置:首页 > 产品设计 > UI/UE

Range Sum Query 2D - Immutable

2017-12-20 00:00 302 查看
问题:

Given a 2D matrix, find the sum of the elements inside the rectangle defined by its upper left corner (row 1, col 1) and lower right corner (row 2, col 2).



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:

You may assume that the matrix does not change.

There are many calls to sumRegion function.

You may assume that row1 ≤ row2 and col 1 ≤ col 2.

解决:

① 直接扫描计算,超时。

class NumMatrix {
int[][] matrix;
public NumMatrix(int[][] matrix) {
this.matrix = matrix;
}
public int sumRegion(int row1, int col1, int row2, int col2) {
int sum = 0;
int i = row1;
int j = col1;
while(i <= row2 && j <= col2){
for (int k = j;k <= col2;k ++){
sum += matrix[i][k];
}
for (int k = i + 1;k <= row2;k ++){
sum += matrix[k][j];
}
i ++;
j ++;
}
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);
*/

② 动态规划。

dp[i][j]表示累计区间(0, 0)到(i, j)这个矩形区间所有的数字之和。

如果我们想要快速求出(r1, c1)到(r2, c2)的矩形区间时,只需

dp[r2][c2] - dp[r2][c1 - 1] - dp[r1 - 1][c2] + dp[r1 - 1][c1 - 1]即可。

如:





(row1, col1) = (2, 1),(row2, col2) = (4, 3)

区域和为:matrix[4][3] - matrix[1][3] - matrix[4][0] + matrix[1][0]。

class NumMatrix { //129ms
int[][] matrix;
int row;
int col;
public NumMatrix(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return;
this.matrix = matrix;
row = this.matrix.length;
col = this.matrix[0].length;
//将每个位置都更新为其和
for (int i = 0;i < row;i ++){
for (int j = 1;j < col;j ++){
this.matrix[i][j] = this.matrix[i][j] + this.matrix[i][j - 1];
}
}
for (int j = 0;j < col;j ++){
for (int i = 1;i < row;i ++){
this.matrix[i][j] = this.matrix[i][j] + this.matrix[i - 1][j];
}
}
}
public int sumRegion(int row1, int col1, int row2, int col2) { //matrix[4][3] - matrix[1][3] - matrix[4][0] + matrix[1][0]
int sum = 0;
if (row1 > 0 && col1 > 0){
sum = matrix[row2][col2] - matrix[row1 - 1][col2] - matrix[row2][col1 - 1] + matrix[row1 - 1][col1 - 1];
}else if (row1 == 0 && col1 > 0){
sum = matrix[row2][col2] - matrix[row2][col1 - 1];
}else if (row1 > 0 && col1 == 0){
sum = matrix[row2][col2] - matrix[row1 - 1][col2];
}else {
sum = matrix[row2][col2];
}
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);
*/

③ 增加一行和一列从而避免matrix为null的情况。



class NumMatrix { //129ms
int[][] preSum;
public NumMatrix(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return;
}
preSum = new int[matrix.length + 1][matrix[0].length + 1];//比matrix 的行列大一,是为了避免matrix为null的情况
for (int i = 0; i < matrix.length; i ++) {//初始化矩阵和
for (int j = 0; j < matrix[i].length; j ++) {
preSum[i + 1][j + 1] = preSum[i + 1][j] + preSum[i][j + 1] - preSum[i][j] + matrix[i][j];
}
}
}
public int sumRegion(int row1, int col1, int row2, int col2) {
int maxRow = Math.max(row1, row2);
int minRow = Math.min(row1, row2);
int maxCol = Math.max(col1, col2);
int minCol = Math.min(col1, col2);
return preSum[maxRow + 1][maxCol + 1] - preSum[maxRow + 1][minCol] - preSum[minRow][maxCol + 1] + preSum[minRow][minCol];
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: