LeetCode 221. 最大正方形--动态规划

该博客探讨了一个二维矩阵中寻找由1组成的最大正方形的问题。通过使用动态规划,作者提出用四个维度的dp数组来分别记录每个位置向右、下、上、左的最大1的连续距离。然后逐步扩大正方形边长,直到无法满足所有边都包含1,从而找到最大正方形的面积。最后,给出了实现这一算法的AC代码。
摘要由CSDN通过智能技术生成
  1. 最大正方形

在一个由 ‘0’ 和 ‘1’ 组成的二维矩阵内,找到只包含 ‘1’ 的最大正方形,并返回其面积。

示例 1:
在这里插入图片描述

输入:matrix = [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,“1”,“1”],[“1”,“0”,“0”,“1”,“0”]]
输出:4

示例 2:

输入:matrix = [[“0”,“1”],[“1”,“0”]]
输出:1

示例 3:

输入:matrix = [[“0”]]
输出:0

提示:

m == matrix.length
n == matrix[i].length
1 <= m, n <= 300
matrix[i][j] 为 '0' 或 '1'

题解

我们这样,因为是正方形,我们直接画斜线,比如一个正方形可以由两个顶点表示(i,j)和(i+k,j+k),然后要求两个顶点里面包含的都是1,构成这样的一个正方形,于是我们可以

dp[i][j][0]表示点(i,j)向右延申的最长距离
dp[i][j][1]表示点(i,j)向下延申的最长距离
dp[i][j][2]表示点(i,j)向上延申的最长距离
dp[i][j][3]表示点(i,j)向左延申的最长距离

那么我们使得k从0开始不断扩大,一定得保证这个过程中始终

dp[i][j][0]>=(k+1) and dp[i][j][1]>=(k+1) and dp[i+k][j+k][2]>=(k+1)  and dp[i+k][j+k][3]>=(k+1)

不断扩大k直到不满足上面的条件,说明此时的k为当前端点可以构成的最大正方形边长。

AC代码

class Solution {
public:
    int dp[305][305][4];
    int maximalSquare(vector<vector<char>>& matrix) 
    {
        memset(dp,0,sizeof(dp));
        for(int i=matrix.size()-1;i>=0;i--)
        {
            for(int j=matrix[i].size()-1;j>=0;j--)
            {
                if(matrix[i][j]=='1')
                {
                    dp[i+1][j+1][0]=dp[i+1][j+2][0]+1;
                    dp[i+1][j+1][1]=dp[i+2][j+1][1]+1;
                }
            }
        }
        for(int i=0;i<matrix.size();i++)
        {
            for(int j=0;j<matrix[i].size();j++)
            {
                if(matrix[i][j]=='1')
                {
                    dp[i+1][j+1][2]=dp[i+1][j][2]+1;
                    dp[i+1][j+1][3]=dp[i][j+1][3]+1;
                }
            }
        }
        int mx=0;
        for(int i=1;i<=matrix.size();i++)
        {
            for(int j=1;j<=matrix[i-1].size();j++)
            {
                for(int k=0;k<=900;k++)
                {
                    if(i+k>matrix.size()||j+k>matrix[i-1].size())break;
                    if(dp[i][j][0]>=(k+1)&&dp[i][j][1]>=(k+1)&&dp[i+k][j+k][2]>=(k+1)&&dp[i+k][j+k][3]>=(k+1))
                    mx=max(mx,k+1);
                    else break;
                }
            }
        }
        return mx*mx;
    }
};

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值