「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战」。
一天都在开车路上,稍微下点雨,路上就堵得不行了。回到家继续刷leetcode。
题目
在一个由 '0' 和 '1' 组成的二维矩阵内,找到只包含 '1' 的最大正方形,并返回其面积。
示例 1:
输入: matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]
输出: 4
示例 2:
输入: matrix = [["0","1"],["1","0"]]
输出: 1
示例 3:
输入: matrix = [["0"]]
输出: 0
思路
这题想了很多,自己没想出来。看了官方题解,发现挺有意思的,记录一下。
定义二维数据dp[i][j],代表以i、j位置的单元格作为正方形右下角的最大正方形边长,给出的状态转移方程是
dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
这个状态转移方程有点难想明白,证明过程如下:
如上图1所示,如果存在dp[i][j] = 4,那么必然存在
- dp[i-1][j] >= 3
- dp[i][j-1] >= 3
- dp[i-1][j-1] >= 3 综合起来,就是
min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) >= dp[i][j] - 1
又如上图2所示,如果存在 dp[i-1][j] >= 3 && dp[i][j-1] >= 3 && dp[i-1][j-1] >= 3 那么必然可以得到,dp[i][j] >= 4,即
dp[i][j] >= min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1 联立上面的2个不等式 dp[i][j] <= min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1 dp[i][j] >= min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
所以可以得到:
dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
Java版本代码
class Solution {
public int maximalSquare(char[][] matrix) {
int max = 0;
int rows = matrix.length;
int cols = matrix[0].length;
int[][] dp = new int[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (i == 0 || j == 0) {
if (matrix[i][j] == '1') {
dp[i][j] = 1;
} else {
dp[i][j] = 0;
}
} else {
if (matrix[i][j] == '1') {
dp[i][j] = Integer.min(Integer.min(dp[i-1][j], dp[i][j-1]), dp[i-1][j-1]) + 1;
} else {
dp[i][j] = 0;
}
}
if (dp[i][j] > max) {
max = dp[i][j];
}
}
}
return max * max;
}
}