221. 最大正方形Leetcode
在一个由
'0'
和'1'
组成的二维矩阵内,找到只包含'1'
的最大正方形,并返回其面积。
题目要求寻找一个内部全部是1的最大正方形,并返回其面积。
思路:用动态规划的方法可以解决。
每个大的正方形一定是由几个小的正方形构成的,比如示例中绿色部分边长为2的正方形是由4个边长为1的正方形构成的,那么同一个大正方形中的不同小正方形与大正方形一定存在某种联系。所以我们只需找出dp数组之间的转移方程即可。
我们不妨假设用每个正方形的右下角方格来存储其所在最大正方形的边长。
1.初始化dp数组
对于一行或者一列的矩阵,我们直接令其dp[i][j]=matrix[i][j]即可;
if(i==0){
if(matrix[i][j]=='1'){
dp[i][j]=1;
if(dp[i][j]>maxs){
maxs=dp[i][j];
}
}
else{
dp[i][j]=0;
}
continue;
}//第一行的dp值
if(j==0){
dp[i][j]=int(matrix[i][j]-'0');
if(dp[i][j]>maxs){
maxs=dp[i][j];
}
continue;
}//第一列的dp值
2.更新dp数组
假设在matrix中的i,j位置(i>0,j>0):
1)若dp[i][j-1]=n,即以[i,j-1]作为右下角的最大正方形边长为n,故以第i,j作为右下角的最大正方形边长小于等于n+1。
2)若dp[i-1][j]=n,即以[i-1,j]作为右下角的最大正方形边长为n,故以第i,j作为右下角的最大正方形边长小于等于n+1。
3)若dp[i-1][j-1]=n,即以[i-1,j-1]作为右下角的最大正方形边长为n,故以第i,j作为右下角的最大正方形边长小于等于n+1。
故可得dp[i][j]<=dp[i][j-1]+1,dp[i][j]<=dp[i-1][j]+1,dp[i][j]<=dp[i-1][j-1]+1,合并,即为
dp[i][j]=min{dp[i][j-1],dp[i-1][j],dp[i-1][j-1]}
if(matrix[i][j]=='1'){//仅当当前位置为1时,其dp值才能更新
dp[i][j]=min(min(dp[i][j-1],dp[i-1][j]),dp[i-1][j-1])+1;
if(dp[i][j]>maxs){
maxs=dp[i][j];
}
}
else{//若当前元素为0,则其dp为0,因为无法构成正方形
dp[i][j]=0;
}
3.完整可执行代码
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
//是否为正方形应该由右下角确定
int n=matrix.size();
int m=matrix[0].size();
int dp[n][m];
int maxs=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(i==0){
if(matrix[i][j]=='1'){
dp[i][j]=1;
if(dp[i][j]>maxs){
maxs=dp[i][j];
}
}
else{
dp[i][j]=0;
}
continue;
}//第一行的dp值
if(j==0){
dp[i][j]=int(matrix[i][j]-'0');
if(dp[i][j]>maxs){
maxs=dp[i][j];
}
continue;
}
if(matrix[i][j]=='1'){
dp[i][j]=min(min(dp[i][j-1],dp[i-1][j]),dp[i-1][j-1])+1;
}
else{
dp[i][j]=0;
}
if(dp[i][j]>maxs){
maxs=dp[i][j];
}
}
}
return maxs*maxs;
}
};
水一道题><