【LeetCode】最大正方形 [M](动态规划)

166 篇文章 1 订阅
该文章是关于LeetCode上的一道编程题,要求在由0和1组成的二维矩阵中找到只包含1的最大正方形并返回其面积。解决方案使用了动态规划(DP)方法,通过构建一个与原矩阵同样大小的dp数组,记录以每个位置为右下角的最大正方形边长。状态转移策略是根据当前位置的左边、上边和左上角的最大边长更新dp值,最终返回dp数组中的最大值的平方作为答案。
摘要由CSDN通过智能技术生成

221. 最大正方形 - 力扣(LeetCode)

一、题目

在一个由 '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

提示:

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

二、代码

class Solution {
    public int maximalSquare(char[][] matrix) {
        int n = matrix.length;
        int m = matrix[0].length;
        // dp[i][j]:正方形必须以(i,j)位置作为右下角,所有可能的正方形里最大的内部全是1的正方形边长有多长
        int[][] dp = new int[n][m];
        // 记录当前收集到的最大正方形的边长
        int max = 0;

        // 赋初值
        // 第一行和第一列的格子作为正方形的右下角,一定最多只能形成边长为1的正方形
        for (int j = 0; j < m; j++) {
            // 如果这个位置为1,那么形成的最大正方形边长就是1
            dp[0][j] = matrix[0][j] == '1' ? 1 : 0;
            // 同步更新max
            if (max < dp[0][j]) {
                max = 1;
            }
        }
        for (int i = 1; i < n; i++) {
            // 如果这个位置为1,那么形成的最大正方形边长就是1
            dp[i][0] = matrix[i][0] == '1' ? 1 : 0;
            // 同步更新max
            if (max < dp[1][0]) {
                max = 1;
            }
        }

        // 构造dp数组
        for (int i = 1; i < n; i++) {
            for (int j = 1; j < m; j++) {
                // 如果当前位置是1,再从左边、上边、左上角三个正方形中求最小正方形的边长是多少,假设是a,那么当前位置的最大正方形边长就是a+1
                // 如果当前位置不是1,那么无法以该位置为正方形的右下角来形成一个内部都是1的正方形,所以边长为0
                dp[i][j] = matrix[i][j] == '1' ? Math.min(dp[i - 1][j], Math.min(dp[i][j - 1], dp[i - 1][j - 1])) + 1 : 0;
                // 更新max
                if (max < dp[i][j]) {
                    max = dp[i][j];
                }
            }
        }
        // 返回最大面积
        return max * max;
    }
}

三、解题思路 

找到全是1的正方形,最大的那个边长有多长。

dp[i][j]:正方形必须以(i,j)位置作为右下角,所有可能的正方形里最大的内部全是1的正方形边长有多长。

例如:dp[2][5] = 3:表示以(2,5)位置为右下角的正方形中,最大的内部全是1的正方形边长为3。

正方形必须以(i,j)位置作为右下角

把每一个位置作为正方形右下角的情况下,最大能有多大都求出来,在dp中求个max答案就出来了。

状态转移策略:

可以用当前位置的左边最大,上面最大和左上角最大的正方形推出以当前位置为右下角的内部都是1的正方形最大是多少。

如果当前位置是1,再从左边、上边、左上角三个正方形中求最小正方形的边长是多少,假设是a,那么当前位置的最大正方形就是(a + 1)*(a + 1)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值