LeetCode热题(JS版) - 221. 最大正方形

250 阅读2分钟

题目描述

给定一个由 0 和 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

解题思路

这道题可以使用动态规划来解决。首先考虑最简单的情况,如果矩阵只有一个元素,那么最大正方形就是该元素本身。接着考虑一个矩阵中只有一行或者一列的情况,此时最大正方形面积也只能是1。当矩阵的大小大于1时,我们可以定义一个相同大小的二维数组 dp 来存储每个位置能够组成的最大正方形边长。

对于任意矩阵中的一个位置 (i,j)(i,j),如果该位置的值为 11,则它能够组成的最大正方形边长为左、上、左上三个位置分别能够组成的最大正方形边长加上当前位置本身构成的正方形边长1。即:

dp(i,j)=min(dp(i1,j),dp(i,j1),dp(i1,j1))+1dp(i,j)=min(dp(i-1,j),dp(i,j-1),dp(i-1,j-1))+1

接着,我们只需要对 dpdp 数组中的所有值取平方并求和,就可以得到最大正方形的面积。

代码实现

function maximalSquare(matrix: string[][]): number {
    const m = matrix.length;
    if (m === 0) {
        return 0;
    }
    const n = matrix[0].length;
    let maxLen = 0;
    const dp: number[][] = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0));
    for (let i = 1; i <= m; i++) {
        for (let j = 1; j <= n; j++) {
            if (matrix[i - 1][j - 1] === '1') {
                dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]) + 1;
                maxLen = Math.max(maxLen, dp[i][j]);
            }
        }
    }
    return maxLen ** 2;
}

上述代码中,我们首先判断矩阵是否为空,然后定义一个二维数组 dp 来存储每个位置能够组成的最大正方形边长。接着,我们循环遍历整个矩阵,如果当前位置为 11,则根据上述公式计算出该位置能够组成的最大正方形边长,并更新 maxLen 的值。最后,我们只需要返回 maxLen 的平方即可。

image.png

复杂度分析

  • 时间复杂度为 O(mn)O(mn)。其中 mmnn 分别代表输入矩阵的行数和列数。我们需要遍历整个矩阵,并对每个位置进行计算,所以总共需要进行 mnmn 次运算。
  • 空间复杂度为 O(mn)O(mn)。我们需要创建一个大小为 (m+1)×(n+1)(m+1)\times(n+1) 的二维数组 dp 来保存计算结果,所以需要额外的 mnmn 的空间。