YunYan

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

 

第一种解法:二维前缀和暴力

维护一个二维的前缀和f[i][j]表示从(1,1)到(i,j)的正方形矩阵的和。f[i][j]=f[i-1][j]+f[i][j-1]-f[i-1][j-1]

然后枚举每个点,并假设该点为右下角顶点,然后枚举正方形长度判断满不满足条件即可,条件为:f[i][j]-f[i-k][j]-f[i][j-k]+f[i-k][j-k]==k*k

code:

class Solution {
public:
    int dp[1000][1000];
    int maximalSquare(vector<vector<char>>& matrix) { 
        int n=matrix.size();
        if(n==0) return 0;
        int m=matrix[0].size();
        
        for(int i=1;i<=n;i++){
            if(matrix[i-1][0]=='1'){
                dp[i][1]+=1+dp[i-1][1];
            }
            else dp[i][1]+=dp[i-1][1];
        }
        for(int i=2;i<=m;i++){
            if(matrix[0][i-1]=='1'){
                dp[1][i]+=dp[1][i-1]+1;
            }
            else dp[1][i]+=dp[1][i-1];
        }
        for(int i=2;i<=n;i++){
            for(int j=2;j<=m;j++){
                dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1];
                if(matrix[i-1][j-1]=='1') dp[i][j]+=1;
            }
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(matrix[i-1][j-1]=='0') continue ;
                int c=min(i,j);
                for(int k=1;k<=c;k++){
                    if(dp[i][j]-dp[i-k][j]-dp[i][j-k]+dp[i-k][j-k]==k*k)
                        ans=max(ans,k*k);
                    else break;
                }
            }
        }
        return ans;
    }
};

 

 第二种解法:dp

定义dp[i][j]表示以(i,j)为右下角点所能构成的正方形的最大边长。

dp[i][j]=min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1])+1

方程证明:

假如说我们dp[i][j]由dp[i-1][j]即i,j上边的点转移过来,因为他是正方形,所以高度和宽度应该同时加一。新正方形以(i,j)为右下角的边长为dp[i-1][j]+1,也就是说从 (i,j)到点(i-dp[i-1][j],j)都应该是1,我们再来看看(i,j-1)这个点,他的正方形边长为dp[i][j-1]。即从(i-1,j)到(i-dp[i][j-1],j-1)都应该是1.所以应该满足i-dp[i][j-1]<=i-dp[i-1][j];即dp[i-1][j]<=dp[i][j-1]。同理可得dp[i-1][j]<=dp[i-1][j-1]即我们选择的总是三个里边最小的。

code:

class Solution {
public:
    int dp[1000][1000];
    int maximalSquare(vector<vector<char>>& matrix) {
        int n=matrix.size();
        if(n==0) return 0;
        int m=matrix[0].size();
        int ans=0;
        for(int i=1;i<=n;i++){
            if(matrix[i-1][0]=='1'){
                 dp[i][1]=1;
                 ans=1;
            }
        }
        for(int j=1;j<=m;j++){
            if(matrix[0][j-1]=='1') {
                dp[1][j]=1;
                ans=1;
            }
        }
        for(int i=2;i<=n;i++){
            for(int j=2;j<=m;j++){
                if(matrix[i-1][j-1]=='1') {
                    dp[i][j]=min(dp[i-1][j],min(dp[i][j-1],dp[i-1][j-1]))+1;
                    ans=max(ans,dp[i][j]);
                }
            }
        }
        return ans*ans;
    }
};

 

posted on 2020-09-08 22:27  Target--fly  阅读(580)  评论(0编辑  收藏  举报