20.12.26 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
提示:
rows == matrix.length
cols == matrix[0].length
0 <= row, cols <= 200
matrix[i][j] 为 '0' 或 '1'
思路
- 想不出来,本来还想着类似于dfs,一看题解发现就完全不相干
- 看了题解思路再自己写代码,没啥太大的问题,除了要注意matrix矩阵是char类型的
- 用一个left二维数组记录matrix里每个元素包括它自己,左边连续为1的个数
- (第一、二层循环)遍历left二维数组,把left作为width。当left为0,则找下一个left
- 当前的ij,是将要确定的矩阵的右上角。(第三层循环)再往行的方向遍历,取新left,更新width,为0即当前根据左上角确定的矩阵的高只能到达0处,跳出循环。
- 第三层循环每次都能找到新high或者新width,更新矩阵大小
- 时间复杂度O(m²n),空间复杂度O(mn),m行n列
- 再看了一下别人的评论,其实不用分开算left数组。第二个循环,前两层循环相同,过程中计算left,当前ij是将要确定的矩阵的右下角。(别人说是暴力解法,唉。。我就是连怎么暴力都想不出来)
代码
class Solution {
public:
int maximalRectangle(vector<vector<char>>& matrix) {
if(matrix.size() == 0) return 0;
vector<vector<int>> left(matrix.size(), vector<int>(matrix[0].size(), 0));
for(int i = 0; i < matrix.size(); ++i){
for(int j = 0; j < matrix[0].size(); ++j){
if(matrix[i][j] == '1'){
if(j == 0) left[i][j] = 1;
else left[i][j] = left[i][j-1] + 1;
}
}
}
int ret = 0;
for(int i = 0; i < matrix.size(); ++i){
for(int j = 0; j < matrix[0].size(); ++j){
if(left[i][j] == 0) continue;
int width = INT_MAX;
for(int k = i; k < matrix.size(); ++k){
width = min(width, left[k][j]);
if(width == 0) break;
ret = max(ret, width * (k - i + 1));
}
}
}
return ret;
}
};