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'

思路

  1. 想不出来,本来还想着类似于dfs,一看题解发现就完全不相干
  2. 看了题解思路再自己写代码,没啥太大的问题,除了要注意matrix矩阵是char类型的
  3. 用一个left二维数组记录matrix里每个元素包括它自己,左边连续为1的个数
  4. (第一、二层循环)遍历left二维数组,把left作为width。当left为0,则找下一个left
  5. 当前的ij,是将要确定的矩阵的右上角。(第三层循环)再往行的方向遍历,取新left,更新width,为0即当前根据左上角确定的矩阵的高只能到达0处,跳出循环。
  6. 第三层循环每次都能找到新high或者新width,更新矩阵大小
  7. 时间复杂度O(m²n),空间复杂度O(mn),m行n列
  8. 再看了一下别人的评论,其实不用分开算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;
    }
};
posted @ 2020-12-26 13:58  肥斯大只仔  阅读(65)  评论(0编辑  收藏  举报