LeeCode 211 暴力 / DP

159 篇文章 1 订阅
题意

传送门 LeeCode 221. 最大正方形

题解
暴力

若矩阵中存在值为 1 1 1 的点,看做边长为 r r r 的正方形的右下顶点,向下、右、右下方合法位置增 1 1 1;遍历全部元素后,值为 4 4 4 的点即为合法正方形的右下顶点,将所有右下顶点位置赋 1 1 1,代表存在以当前位置为右下顶点的,边长为 r + 1 r+1 r+1 的正方形,其余赋 0 0 0;重复第一步直到不存在可新增边长的正方形。

class Solution {
public:
    int di[4] = {0, 0, 1, 1};
    int dj[4] = {0, 1, 1, 0};
    int n, m;
    vector<vector<int>> mat1, mat2;
    int solve(){
        bool f;
        int r = 1;
        do{
            f = 0;
            mat2.assign(n, vector<int> (m, 0));
            for(int i = 0; i < n; i++){
                for(int j = 0; j < m; j++){
                    if(mat1[i][j] == 1){
                        for(int k = 0; k < 4; k++){
                            int ni = i + di[k], nj = j + dj[k];
                            if(ni >= 0 && ni < n && nj >= 0 && nj < m){
                                mat2[ni][nj]++;
                            }
                        }
                    }
                }
            }
            mat1.assign(n, vector<int> (m, 0));
            for(int i = 0; i < n; i++){
                for(int j = 0; j < m; j++){
                    if(mat2[i][j] == 4){
                    	// 存在边长更大的正方形
                        f = 1;
                        mat1[i][j] = 1;
                    }
                }
            }
            ++r;
        }while(f);
        --r;
        return r * r;
    }
    int maximalSquare(vector<vector<char>>& matrix) {
        if(matrix.size() == 0) return 0;
        n = matrix.size(), m = matrix[0].size();

        bool f = 0;
        mat1.resize(n, vector<int> (m, 0));
        for(int i = 0; i < n ; i++){
            for(int j = 0; j < m; j++){
                if(matrix[i][j] == '1') mat1[i][j] = 1, f = 1;
            }
        }
        if(!f) return 0;
        int res = solve();
        return res;
    }
};
DP

按照暴力的思路, d p [ i ] [ j ] dp[i][j] dp[i][j] 代表位置 ( i , j ) (i,j) (i,j) 为右下顶点的正方形的最大边长

d p [ i ] [ j ] = m i n ( d p [ i − 1 ] [ j − 1 ] , d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] ) + 1 dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1 dp[i][j]=min(dp[i1][j1],dp[i1][j],dp[i][j1])+1

class Solution {
public:
    int n, m;
    vector<vector<int>> dp;
    int maximalSquare(vector<vector<char>>& matrix) {
        if((n = matrix.size()) == 0 || (m = matrix[0].size()) == 0) return 0;

        int res = 0;
        dp.resize(n, vector<int> (m, 0));
        for(int i = 0; i < m; i++){
            if(matrix[0][i] == '1') res = dp[0][i] = 1;
        }
        for(int i = 0; i < n; i++){
            if(matrix[i][0] == '1') res = dp[i][0] = 1;
        }
        for(int i = 1; i < n ; i++){
            for(int j = 1; j < m; j++){
                if(matrix[i][j] == '1'){
                    dp[i][j] = min(dp[i-1][j-1], min(dp[i-1][j], dp[i][j-1])) + 1;
                    res = max(res, dp[i][j]);
                }
            }
        }
        return res * res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值