首先和最大矩形差不多,用单调栈,面积计算的时候正方形的值选高度和宽度的最小值。
class Solution {
public:
int incr_stack(int height[],int m){
stack<int> s;
s.push(-1);
int ans=0;
for(int i=0;i<m;i++){
while(s.top()!=-1 && height[s.top()]>=height[i]){
int mid_pos=s.top();
s.pop();
int len=min(height[mid_pos],(i-s.top()-1));
ans=max(ans,len*len);
}
s.push(i);
}
while(s.top()!=-1){
int mid_pos=s.top();
s.pop();
int len=min(height[mid_pos],(m-s.top()-1));
ans=max(ans,len*len);
}
return ans;
}
int maximalSquare(vector<vector<char>>& matrix) {
int n=matrix.size();
if(n==0)
return 0;
int m=matrix[0].size();
int height[m];
memset(height,0,sizeof(height));
int ans=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(matrix[i][j]=='0')
height[j]=0;
else
height[j]=height[j]+1;
}
ans=max(ans,incr_stack(height,m));
}
return ans;
}
};
然后就是动态规划了。使用正方形拼接。
dp[i][j]表示以i,j作为右下角的正方形的最大长度。统计向上和向左的连续最大长度,然后可以从左边、上边、左上的那三个正方形拼接出来。
class Solution {
public:
int maximalSquare(vector<vector<char>>& matrix) {
int n=matrix.size();
if(n==0)
return 0;
int m=matrix[0].size();
int dp[n][m];
int height[m];
int left[m];
memset(dp,0,sizeof(dp));
memset(height,0,sizeof(height));
memset(left,0,sizeof(left));
int ans=0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
dp[i][j]=matrix[i][j]=='1'?1:0;
height[j]=matrix[i][j]=='1'?height[j]+1:0;
if(matrix[i][j]=='1'){
if(j-1>=0)
left[j]=left[j-1]+1;
else
left[j]=1;
}
else
left[j]=0;
if(matrix[i][j]=='0')
continue;
if(j-1>=0)
dp[i][j]=max(dp[i][j],min(height[j],dp[i][j-1]));
if(i-1>=0)
dp[i][j]=max(dp[i][j],min(left[j],dp[i-1][j]));
if(i-1>=0 && j-1>=0)
dp[i][j]=max(dp[i][j],min(left[j],min(dp[i-1][j-1]+1,height[j])));
ans=max(ans,dp[i][j]*dp[i][j]);
}
}
return ans;
}
};