LeetCode 85 Maximal Rectangle (Tag:Array Difficulty:Hard)

68 阅读2分钟

这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战

前言

关于 LeetCode 数组类型题目的相关解法,可见LeetCode 数组类型题目做前必看,分类别解法总结了题目,可以用来单项提高。觉得有帮助的话,记得多多点赞关注哦,感谢!

题目描述

给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 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"]]
输出:6
解释:最大矩形如上图所示。

示例 2:
输入:matrix = []
输出:0

示例 3:
输入:matrix = [["0"]]
输出:0

示例 4:
输入:matrix = [["1"]]
输出:1

示例 5:
输入:matrix = [["0","0"]]
输出:0

链接:leetcode-cn.com/problems/ma…

题解

  1. 动态规划。动态规划难点在于构造 dp 数组,本题构造 dp 数组为 dp[i][j], 表示对于第 i 行,第 j 列连续的 1 值的大小。有转移公式

    dp[i][j] = matrix[i][j] === 0 ? 0 : dp[i][j-1] + 1

    在得到 dp 数组之后,我们可以遍历每个 dp 数组的值,拿到宽度,再向下扩展拿到高度,计算面积。具体代码如下,时间复杂度 O(mn^2)

/**
 * @param {character[][]} matrix
 * @return {number}
 */
var maximalRectangle = function(matrix) {
    const m = matrix.length
    if (m === 0) return 0
    const n = matrix[0].length
    const dp = Array.from({ length: m }, () => (new Array(n)))
    
    for (let i = 0; i < m; i++) {
        for (let j = 0; j < n; j++) {
            dp[i][j] = (matrix[i][j] == '1') ? (j == 0 ? 1 : dp[i][j - 1] + 1) : 0;
        }
    }
    
    let ans = 0;
    for (let i = 0; i < m; ++i) {
      for (let j = 0; j < n; ++j) {
        let len = Number.MAX_VALUE;
        for (let k = i; k < m; k++) {
          len = Math.min(len, dp[k][j]);
          if (len == 0) break;
          ans = Math.max(len * (k - i + 1), ans);
        }
      }
    }
    return ans
};
  1. 利用 leetcode 84 的单调栈解法,对于每一列,我们采用单调栈来计算最大面积。时间复杂度为 O(mn)。