题目
在一个由 '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
提示:
m == matrix.length
n == matrix[i].length
1 <= m, n <= 300
matrix[i][j]
为'0'
或'1'
题解
解题思路
这道题可以使用动态规划来解决。
假如用 dp[i][j] 表示以第 i 行第 j 列元素为右下角的只包含 '1' 最大正方形的边长,现在要考虑如何求得该值,既然是右下角,所以只需要考虑如何通过当前元素的左、左上、上这三个元素对应的 dp 值来得到 dp[i][j] 的值。
状态转移方程
如果 matrix[i][j] == '0',那么 dp[i][j] 显然是为 0 的,这点很好理解,主要是需要考虑 matrix[i][j] == '1'的情况。可以观察到,dp[i][j] 可以从左、左上、上这三个元素对应 dp 值中取最小值再加 1 得到,因此当 matrix[i][j] == '1' 时状态转移方程如下:
dp[i][j] = min(dp[i][j-1], dp[i-1][j-1], dp[i-1][j]) + 1
边界值
当 i = 0 时,由于上侧和左上侧没有元素,所以 dp[i-1][j-1], dp[i-1][j] 可以当做 0 处理;
当 j = 0 时,由于左侧和左上侧没有元素,所以 dp[i][j-1], dp[i-1][j-1] 可以当做 0 处理。
从矩形左上角第一个元素开始,逐一处理即可,最终 dp 数组中的最大值即为最大正方形的边长,平方求得面积返回即可。
代码
class Solution {
public int maximalSquare(char[][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
int[][] dp = new int[m + 1][n + 1];
int ans = 0;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (matrix[i-1][j-1] == '0') {
continue;
}
dp[i][j] = Math.min(dp[i-1][j], Math.min(dp[i-1][j-1], dp[i][j-1])) + 1;
if (dp[i][j] > ans) {
ans = dp[i][j];
}
}
}
return ans * ans;
}
}
复杂度分析
- 时间复杂度:O(mn)
m 为矩形的行数,n 为矩形的列数。 - 空间复杂度:O(mn) 使用 dp 数组的空间开销。
优质项目推荐
推荐一个可用于练手、毕业设计参考、增加简历亮点的项目。
lemon-puls/txing-oj-backend: Txing 在线编程学习平台,集在线做题、编程竞赛、即时通讯、文章创作、视频教程、技术论坛为一体
公众号
有兴趣可以关注公众号一起学习更多的干货哈!