题目
在一个由 '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
解题思路:动态规划
👉 定义: 表示以
为右下角,且只包含
的正方形的边长最大值。
如果我们能计算出所有 的值,那么其中的最大值即为矩阵中只包含
的正方形的边长最大值,其平方即为最大正方形的面积。
那么如何计算 中的每个元素值呢?对于每个位置
,检查在矩阵中该位置的值:
如果该位置的值是
,则
,因为当前位置不可能在由
组成的正方形中;
如果该位置的值是
,则
的值由其上方、左方和左上方的三个相邻位置的
值决定。
状态转移方程:具体而言,当前位置的元素值等于三个相邻位置的元素中的最小值加
此外,还需要考虑边界条件。如果 和
中至少有一个为
,则以位置
为右下角的最大正方形的边长只能是
,因此
。
以下用一个例子具体说明。原始矩阵如下。
0 1 1 1 0
1 1 1 1 0
0 1 1 1 1
0 1 1 1 1
0 0 1 1 1
对应的 值如下。
0 1 1 1 0
1 1 2 2 0
0 1 2 3 1
0 1 2 3 2
0 0 1 2 3
复杂度分析
时间复杂度:,其中
和
是矩阵的行数和列数,需要遍历原始矩阵中的每个元素计算
的值。
空间复杂度:,其中
和
是矩阵的行数和列数 。
- 创建了一个和原始矩阵大小相同的矩阵 。由于状态转移方程中的 由其上方、左方和左上方的三个相邻位置的 值决定,因此可以使用两个一维数组进行状态转移,空间复杂度优化至 。
官方代码
class Solution {
public int maximalSquare(char[][] matrix) {
int maxSide = 0;
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return maxSide;
}
int rows = matrix.length, columns = matrix[0].length;
int[][] dp = new int[rows][columns];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
if (matrix[i][j] == '1') {
if (i == 0 || j == 0) {
dp[i][j] = 1;
} else {
dp[i][j] = Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
}
maxSide = Math.max(maxSide, dp[i][j]);
}
}
}
int maxSquare = maxSide * maxSide;
return maxSquare;
}
}