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;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章