zoukankan      html  css  js  c++  java
  • Leetcode 最大正方形(两种解法)

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

    维护一个二维的前缀和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;
        }
    };
  • 相关阅读:
    创建用户中遇到的问题
    创建用户和用户组
    ActiveMq在linxu系统上的启动
    CentOs 6.5 安装jdk
    卸载CentOs6.5自带的OpenJDK
    centos 6.5 添加ip地址
    CentOs 6.5的安装
    jna的简单测试
    电脑硬盘空间怎么越来越小
    build path contains duplicate entry:'src' for project 'XXX'
  • 原文地址:https://www.cnblogs.com/Accepting/p/13636088.html
Copyright © 2011-2022 走看看