携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情 >>
一、题目描述 LeetCode - 85
给定一个仅包含 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
二、解题思路
本题要求返回矩阵中的最大矩形面积,与求“最大正方形”一样,可以考虑使用动态规划来求解。
在构建状态转移方程时,使用dp[i][j]代表在矩阵matrix[i][j]点左边连续1的数量,然后对于矩阵中任意一个点,依次计算以该点为矩形右下角顶点的矩形面积,取最大值即可。在计算面积时需要考虑矩形的宽度,既dp[i][j]应该取较小的值。
注意,在求每个矩形的面积时需要判断矩形的宽度应该取dp数组列的哪个值合适。防止取到无法构成矩形的宽度。
三、代码
class Solution {
public int maximalRectangle(char[][] matrix) {
int res = 0;
int row = matrix.length;
int col = matrix[0].length;
int[][] dp = new int[row][col];
for (int i = 0; i < row; i++) {
if (matrix[i][0] == '1'){
dp[i][0] = 1;
}
for (int j = 1; j < col; j++) {
if (matrix[i][j] == '1') {
dp[i][j] = dp[i][j - 1] + 1;
}
}
}
res = 0;
for (int i=0; i<row; i++){
for (int j=0; j<col; j++){
int k = dp[i][j];
int area = k;
for(int m=i-1; m>=0; m--){
k = Math.min(dp[m][j], k);
area = Math.max(area, k * (i+1-m));
}
res = Math.max(res, area);
}
}
return res;
}
}
四、总结
本题使用动态规划求解,解法类似求最大正方形,都是考虑由右下角顶点构成矩形的面积,最后求最大值。时间复杂度为O(m^2*n),空间复杂度为O(mn),其中m为矩阵的行数,n为矩阵的列数。