221. 最大正方形 难度中等
老规矩 直接上题
在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。
前台样例
示例:
输入:
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
输出: 4
说实话,这个题我还真不会做,一开始连思路都没有,也是自己太笨了
其实蛮力法就可以
蛮力法思路:把每一个‘1’的点都当作正方形的左上角 不断的扩大横向与纵向来求该点的最大的边长,所有1中最大的边长就是我们需要的
注意一点:结束条件是搜索到边界了或者是正方形内有0了
有可能是没0但是搜索到头了,这种情况应该是A-a
而如果是因为有0了 应该是A-a-1.
class Solution {
public:
int getmaxlen(vector<vector<char>>& matrix,int a,int b)
{
//对于每一个1 都当成左上角点
int maxlen=1;
int l1=matrix.size();
int l2=matrix[0].size();
bool flag=true;
int A=a,B=b;
while(1)
{
if(A>=l1||B>=l2||flag==false) break;
A++; B++;
for(int i=a;i<l1&&i<A;i++)
for(int j=b;j<l2&&j<B;j++)
{
if(matrix[i][j]=='0') {flag=false;break;}
}
}
if(flag==false)maxlen=max(A-a-1,1);
else maxlen=max(A-a,1);
return maxlen;
}
int maximalSquare(vector<vector<char>>& matrix) {
int l1=matrix.size();if (matrix.size() == 0)return 0;
int l2=matrix[0].size();if (matrix[0].size() == 0)return 0;
int maxlen=0;
for(int i=0;i<l1;i++)
for(int j=0;j<l2;j++)
{
if(matrix[i][j]=='1') //找到1
maxlen=max(getmaxlen(matrix,i,j),maxlen); //更新maxlen
}
return maxlen*maxlen;
}
};
第二种解法 --DP
对于每个位置 (i, j),检查在矩阵中该位置的值:
如果该位置的值是 0,则 dp(i, j) = 0,因为当前位置不可能在由 1 组成的正方形中;
如果该位置的值是 1,则 dp(i, j) 的值由其上方、左方和左上方的三个相邻位置的 dp 值决定。具体而言,当前位置的元素值等于三个相邻位置的元素中的最小值加 1,状态转移方程如下:
dp(i, j)=min(dp(i−1, j), dp(i−1, j−1), dp(i, j−1))+1
注意 min不能写三个参数
这个DP方程有了,写出来就蛮简单的
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
int l1=matrix.size();if (matrix.size() == 0)return 0;
int l2=matrix[0].size();if (matrix[0].size() == 0)return 0;
int maxlen=0;
int flag[1010][1010];//DP
for(int i=0;i<l1;i++)
for(int j=0;j<l2;j++)
{
if(matrix[i][j]=='1') flag[i][j]=1;
if(matrix[i][j]=='0') flag[i][j]=0;
if(flag[i][j]==1&&i-1>=0&&j-1>=0)
flag[i][j]=min(min(flag[i-1][j],flag[i-1][j-1]),flag[i][j-1])+1;
//cout<<flag[i][j]<<endl;
maxlen=max(maxlen,flag[i][j]);
}
return maxlen*maxlen;
}
};