在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。
示例:
输入:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
输出: 4
思路:该方法复杂度较高,能勉强通过这道题,相信有更优的解法。
我是通过求每一行的前缀和使得减少一层for循环来实现的。
class Solution {
public int maximalSquare(char[][] matrix) {
int m=matrix.length;
if(m==0) return 0;
int n=matrix[0].length;
int[][] sum=new int[m][n];
int ans=0;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
if(j==0)
sum[i][j]=matrix[i][j]=='1'?1:0;
else
sum[i][j]=matrix[i][j]=='0'?0:sum[i][j-1]+(matrix[i][j]=='1'?1:0);
}
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
int tmp=Integer.MAX_VALUE;
for(int h=i;h<m;h++)
{
tmp=Math.min(tmp,sum[h][j]);
if(tmp>=h-i+1)
ans=Math.max(ans, (h-i+1)*(h-i+1));
else
ans=Math.max(ans, tmp*tmp);
}
}
return ans;
}
}
方法二:动态规划
我们设dp[i][j]为以(i,j)为正方形右下角的最大正方形,则我们可以得到递推式
dp[i][j]=min(dp[i][j-1],dp[i-1][j],dp[i-1][j-1])+matrix[i][j]==‘1’?1:0;
class Solution {
public int maximalSquare(char[][] matrix) {
int m=matrix.length;
if(m==0) return 0;
int n=matrix[0].length;
int[][] dp=new int[m][n];
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
{
if(matrix[i][j]=='0')
continue;
if(i==0 || j==0)
dp[i][j]=1;
else
dp[i][j]=Math.min(dp[i-1][j-1], Math.min(dp[i-1][j], dp[i][j-1]))+1;
}
int ans=0;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
ans=Math.max(ans, dp[i][j]*dp[i][j]);
return ans;
}
}