这是我参与11月更文挑战的第10天,活动详情查看:2021最后一次更文挑战
前言
关于 LeetCode 数组类型题目的相关解法,可见LeetCode 数组类型题目做前必看,分类别解法总结了题目,可以用来单项提高。觉得有帮助的话,记得多多点赞关注哦,感谢!
题目描述
给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。
示例 1:
输入: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…
题解
-
动态规划。动态规划难点在于构造 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
};
- 利用 leetcode 84 的单调栈解法,对于每一列,我们采用单调栈来计算最大面积。时间复杂度为 O(mn)。