leetcode - [栈、动态规划] - 最大矩形(85)

1、问题描述

给定一个只包含0、1的二进制二维矩阵,找出只包含1的最大矩形,并返回其最大面积。
示例:

输入:
[
[“1”,“0”,“1”,“0”,“0”],
[“1”,“0”,“1”,“1”,“1”],
[“1”,“1”,“1”,“1”,“1”],
[“1”,“0”,“0”,“1”,“0”]
]
输出: 6

2、解题思路

思路1暴力法。列举所有以(x1,y1),(x2,y2)(x_1,y_1),(x_2,y_2)为左上角和右下角顶点的矩形,取其中最大矩形的面积。
时间复杂度:O(N3M3)O(N^3M^3),因为遍历所有的顶点两次,再加上遍历以这两个顶点为对角顶点的矩形面积有需要耗费O(NM)O(NM)时间。
空间复杂度:O(1)O(1)

思路2:这道题其实和[leetcode - [栈] - 柱状图的最大矩形(84)]是一样的,它只不过是将其扩展为了二维的,不信看下图橙色部分:
在这里插入图片描述
因此,
(1)对于矩阵中第i行的每个元素matrix[i][j],j=1,2,...,Mmatrix[i][j],j=1,2,...,M,计算从上边界开始到matrx[i][j]matrx[i][j]连续的1的个数,并存储在矩阵h[i][j]h[i][j]中;
(2)h[i]h[i]中第ii行的值看成是柱状图的柱子的高度,求柱状图的最大矩形面积;

3、代码实现

/*算法思想:转换成求柱状图的最大矩形,如何转化?
(1)对于矩阵中第i行的每个元素matrix[i][j],计算从上边界开始到matrx[i][j]连续的1的个数,并存储在矩阵h[i][j]中;
(2)h中第i行的值看成是柱状图的柱子的高度,求柱状图的最大矩形面积;
*/
class Solution {
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        int rows = matrix.size();
        int cols = rows > 0 ? matrix[0].size() : 0;
        vector<vector<int>> h(rows, vector<int>(cols,0));
        for(int c = 0; c < cols; c++){
            for(int r = 0; r < rows; r++){
                if(matrix[r][c] == '0'){
                    h[r][c] = 0;
                }
                else if(matrix[r][c] == '1'){
                    if(r > 0 && matrix[r-1][c] == '1'){
                        h[r][c] = h[r-1][c] + 1;
                    }
                    else{
                        h[r][c] = 1;
                    }
                }
                // cout<<"h["<<r<<"]["<<c<<"]="<<h[r][c]<<endl;
            }
        }
        
        int area  = 0;
        for(int i = 0; i < rows; i++){
            // cout<<"maxArea["<<i<<"]="<<maxArea(h[i])<<endl;
            area = max(area, maxArea(h[i]));
        }
        return area;
        
    }

    int maxArea(vector<int>& height){
        int len = height.size();
        stack<int> s;
        //压入height[0]的左边界索引;
        s.push(-1);
        int maxarea = 0;
        for(int i = 0; i < len; i++){
            while(s.top() != -1 && height[i] < height[s.top()]){
                int top = s.top();
                s.pop();
                maxarea = max(maxarea, height[top] * (i - s.top() - 1));
            }
            s.push(i);
        }
        while(s.top() != -1){
            int top = s.top();
            s.pop();
            maxarea = max(maxarea, height[top] * (len - s.top() - 1));
        }

        return maxarea;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章