力扣【动态规划专题】221. 最大正方形

269 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第 21 天,点击查看活动详情

题目链接

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

题目描述

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

测试用例

用例1:

image.png

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

限制

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

题目分析

题目需要我们在一个二维的矩阵里,找一个由 1 组成的最大的正方形,而矩阵里的元素只有 01

对于矩阵中的某个坐标 arr[i][j],如果他的值为 1,则以这个节点为正方形的右下节点,然后去检查 arr[i-1][j], arr[i][j-1], arr[i-1][j-1] 三个节点,如果都为 1 则表示这个 2x2 的矩形满足要求

以如下的矩形示例:

matrix = [    ["1","1","1"],
    ["1","1","1"],
    ["1","1","1"]]

第一行第一列保持不变,从第2行 第2列开始,以当前的元素作为 2x2 矩形的右下角节点,标记当前可以形成的最大矩形,矩形替换后的效果如下:

matrix = [    ["1","1","1"],
    ["1","2","2"],
    ["1","2","3"]]

发现 arr[i][j] 与他所在的 2x2 矩形的其他 3 个节点存在某种关系

更换另一个示例:

matrix = [
    ["1","1","0"],
    ["1","1","1"],
    ["1","1","1"]]
    
// 替换后效果
matrix = [
    ["1","1","0"],
    ["1","2","1"],
    ["1","2","2"]]

推测出一个结论:arr[i][j] = Math.min(arr[i-1][j], arr[i][j-1], arr[i-1][j-1]) + 1,表示分别以 arr[i-1][j], arr[i][j-1], arr[i-1][j-1] 为右下角矩形可以得到的最大矩形,在此基础得到 arr[i][j] 可以表示的最大矩形

接下来,我们只需要对二维数组进行遍历并更新表中的数据,记录下最大值即可

代码实现

完整的代码实现如下

var maximalSquare = function (matrix) {
        let max = 0;
        for (let i = 0; i < matrix.length; i++) {
            let arr = matrix[i];
            for (let j = 0; j < arr.length; j++) {
                if (arr[j] == 0) continue;
                if (i != 0 && j != 0) {
                    arr[j] = Math.min(arr[j - 1], matrix[i - 1][j], matrix[i - 1][j - 1]) + 1;
                }
                max = Math.max(max, arr[j]);
            }
        }
        return max * max;
    };

image.png