LeetCode304. 二维区域和检索
昨天一维区域和检索就有题友猜测3月会是DP月,所言不差,盲猜明天还是中等题。
题目描述:
给定一个二维矩阵,计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2)。
思路:
我们用dp[i][j]
表示以(0,0)为左上角,(i,j)为右下角
的子矩阵的元素和。
dp[0][0]=3
dp[1][1]=3+0+5+6=14
我们通过四个子矩阵求解 sumRegion(r1,c1,r2,c2)
绿色子矩阵的元素和= 紫色矩阵-黄色矩阵-蓝色矩阵+红色矩阵(以为黄色和蓝色将红色区域减少了两次),而紫色矩阵,黄色矩阵,蓝色矩阵,红色矩阵都是以(0,0)
为左上角的子矩阵,对应一个d[i][j],稍加分析可得:
- 红色矩阵以
(r1-1,c1-1)
为右下角,因为的右下角在绿色矩阵左上角的左上方(少一行,少一列),对应dp[r1-1][c1-1]
- 蓝色矩阵以
(r1-1,c2)
为右下角,因为它的右下角与c2同列,比r1少一行,对应dp[r1-1][c2]
- 黄色矩阵以
(r2,c1-1)
为右下角,因为它的右下角与r2同行,比c1少一列,对应dp[r2][c1-1]
- 紫色就不讲了嘛
可以是dp怎么求呢?
d p [ i ] [ j ] = d p [ i − 1 ] [ j ] + d p [ i ] [ j − 1 ] − d p [ i − 1 ] [ j − 1 ] + m a t r i x [ i ] [ j ] dp[i][j] = dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+matrix[i][j] dp[i][j]=dp[i−1][j]+dp[i][j−1]−dp[i−1][j−1]+matrix[i][j]。其实和sumReginon()是同样的道理,将dp[i][j]当成子矩阵,在矩阵图上画画就明白了,就不细述了,多思考。。
以上讲解都没有设计下标溢出,不过代码中写了,多思考啊
class NumMatrix {
int[][] dp;
public NumMatrix(int[][] matrix) {
dp = matrix;
if(matrix.length==0||matrix[0].length==0) return;
for (int i = 1; i < matrix[0].length; i++) {
dp[0][i] += dp[0][i-1];
}
for (int i = 1; i <matrix.length ; i++) {
dp[i][0] += dp[i-1][0];
}
for (int i = 1; i <dp.length ; i++) {
for (int j = 1; j < dp[0].length; j++) {
dp[i][j]+= dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1];
}
}
}
public int sumRegion(int row1, int col1, int row2, int col2) {
return dp[row2][col2] - (row1==0?0:dp[row1-1][col2]) - (col1==0?0:dp[row2][col1-1])
+(row1==0||col1==0?0:dp[row1-1][col1-1]);
}
}