在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。
示例:
输入:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
输出: 4
不需要额外空间 直接原地dp
写得有点丑,没有大佬们的好看。
第一个for遍历1~max_edge,也就是最长的边。
第二三个for,判断matrix[i][j]=='1' && matrix[i-1][j]=='1' && matrix[i][j-1]=='1' && matrix[i-1][j-1]=='1',也就是当前位置,以及它左上角的位置,以及左边的位置,上边的位置都为1,说明可以组成边长为当前len的正方形。注意len为1时只要找到一个就可以break了,len>1时,比如len==2,要遍历所有可能的位置,更新matrix[i][j],这个是接下来len++后判断需要使用的。最后可以做的剪枝,若在当前len下不能更新找到更大的正方形,则接下来更不可能找到了,直接break。
【注意】:这个matrix在不同的len下含义的不同的喔。
public static int maximalSquare(char[][] matrix) {
if (matrix==null || matrix.length==0 || matrix[0]==null || matrix[0].length==0) return 0;
int row = matrix.length;
int col = matrix[0].length;
int max_edge = Math.min(row, col);
int max_area = 0;
for (int len = 1;len<=max_edge;len++){
boolean flag = false;
for (int i = row-1;i>=len-1;i--){
for (int j = col-1;j>=len-1;j--){
if (matrix[i][j]=='1' && len==1) {
max_area = Math.max(max_area, len * len);
flag = true;
break;
}
if (len!=1) {
if (matrix[i][j]=='1' && matrix[i-1][j]=='1' &&
matrix[i][j-1]=='1' && matrix[i-1][j-1]=='1'){
flag=true;
max_area = Math.max(max_area, len*len);
}else {
matrix[i][j]=0;
}
}
}
if (flag && len==1) break;
}
if (flag==false)
break;
}
return max_area;
}
动态规划
我们用一个例子来解释这个方法:
0 1 1 1 0
1 1 1 1 1
0 1 1 1 1
0 1 1 1 1
0 0 1 1 1
- 我们用 0 初始化另一个矩阵 dp,维数和原始矩阵维数相同;
- dp(i,j) 表示的是由 1 组成的最大正方形的边长;
- 从 (0,0) 开始,对原始矩阵中的每一个 1,我们将当前元素的值更新为
dp(i, j)=min(dp(i−1, j), dp(i−1, j−1), dp(i, j−1))+1 - 我们还用一个变量记录当前出现的最大边长,这样遍历一次,找到最大的正方形边长 maxsqlen,那么结果就是 maxsqlen^2。
可以通过下面的图来理解该工作原理:

public class Solution {
public int maximalSquare(char[][] matrix) {
int rows = matrix.length, cols = rows > 0 ? matrix[0].length : 0;
int[][] dp = new int[rows + 1][cols + 1];
int maxsqlen = 0;
for (int i = 1; i <= rows; i++) {
for (int j = 1; j <= cols; j++) {
if (matrix[i-1][j-1] == '1'){
dp[i][j] = Math.min(Math.min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;
maxsqlen = Math.max(maxsqlen, dp[i][j]);
}
}
}
return maxsqlen * maxsqlen;
}
}
复杂度分析
- 时间复杂度:O(mn)O(mn)。
- 空间复杂度:O(mn)O(mn),用了一个大小相同的矩阵 dp。
最大正方形算法解析
本文详细解析了在由0和1组成的二维矩阵中寻找最大正方形的问题,通过动态规划的方法,利用一个同样维数的dp矩阵,实现了高效求解最大正方形边长的过程。
1851

被折叠的 条评论
为什么被折叠?



