携手创作,共同成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情
最大矩形
给定一个仅包含
0
和1
、大小为rows x cols
的二维二进制矩阵matrix,找出只包含1
的最大矩形,并返回其面积。
分析
- 之前在写柱状图中最大矩形的时候,使用的是单调栈,但是最近在写了很多动态规划之后,觉得在矩阵中的最大矩形也可以使用动态规划来实现
动态规划
- 定义状态:dp[i][j]表示矩阵matrix的第i行第j列的矩形面积
- 状态初始化:对矩阵按行遍历,dp[0]和matrix的第一行一样
- 状态转移:
- 如果dp[i][j]是1,dp[i][j] = dp[i-1]j+1
- 如果dp[i][j]是0,dp[i][j] = 0
- 得到有状态的dp数组后,不能直接得到答案,需要对当前行遍历,找到本行的最小值然后乘矩阵cell的个数从而得到最大矩形的面积值
代码
/**
* @param {character[][]} matrix
* @return {number}
*/
var maximalRectangle = function(matrix) {
if (matrix.length <= 0) return 0;
let n = matrix.length;
let m = matrix[0].length;
let dp = new Array(n).fill().map(() => new Array(m).fill(0));
let maxArea = 0;
for (let i = 0; i < n; i++) {
for (let j = 0; j < m; j++) {
if (i == 0){
dp[i][j] = matrix[i][j] == '1' ? 1 : 0;
} else {
dp[i][j] = matrix[i][j] == '1' ? (dp[i-1][j] + 1) : 0;
}
let min = dp[i][j];
for (let k = j; k >= 0; k--) {
if (min == 0) break;
if (dp[i][k] < min) min = dp[i][k];
maxArea = Math.max(maxArea, min * (j - k + 1));
}
}
}
return maxArea;
}
};
总结
- 动态规划的题目有很多的变化,状态dp有一维数组、二维数组,有些题目dp[x]或者dp[x][y]就是所得答案,也有维护了状态之后,需要对这个状态的数据进一步的分析得到答案,但是核心都是一样的,动态规划的题目中都有“状态”,以及“状态”的转移,至于状态怎么转移,和怎么定义状态有关,如果定义的状态不一样,状态转移方程也会不同,因此在解动态转移题目或者看题解的时候,更多的需要感受在某种定义下的状态是如何转移的,根据不同的情况,写出转移方程,这样主体的代码就可以写出来了。再加一些某些特定题目的特殊情况处理,一般都可以很好的解决问题
- 动态规划作为常用的解题方法,最近写的比较多,这篇作为动态规划的完结篇,动态规划就暂告一个段落了
- 今天也是有收获的一天