LeetCode 221. 最大正方形

https://leetcode-cn.com/problems/maximal-square/

首先和最大矩形差不多,用单调栈,面积计算的时候正方形的值选高度和宽度的最小值。

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;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值