【LeetCode】085. Maximal Rectangle

题目:

Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.

For example, given the following matrix:

1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
Return 6
 

题解:

  这个题是在 Largest Rectangle in Histogram上的延伸,二维矩阵每一行为底,都可以看做一个直方图,输入矩阵有多少行,就可以形成多少个直方图,循环调用直方图最大面积函数即可。

Solution 

class Solution {
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        int res = 0;
        if(matrix.empty())
            return res;
        int n = matrix[0].size();
        vector<int> cals(n, 0);
        for(int i = 0; i < matrix.size(); ++i){
            for(int j = 0; j < n; ++j){
                cals[j] = matrix[i][j] == '0' ? 0 : cals[j] + 1;
            }
            res = max(res, maxRectangleArea(cals));
        }
        return res;
    }
private:
    int maxRectangleArea(vector<int> &nums){
        int n = nums.size();
        int res = 0, area = 0;
        nums.push_back(0);
        stack<int> s;
        for(int i = 0; i <= n;){
            if(s.empty() || nums[s.top()] <= nums[i])
                s.push(i++);
            else {
                int cur = s.top(); s.pop();
                area = nums[cur] * (s.empty() ? i : (i - s.top() - 1));
                res = max(res, area);
            }
        }
        return res;
    }
};

  left数组表示左边界是1的位置,right数组表示右边界是1的位置,那么对于任意一行的第j个位置,矩形为(right[j] - left[j]) * height[j]

Solution 2 动态规划

class Solution {
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        int res = 0;
        if(matrix.empty())
            return res;
        int n = matrix[0].size();
        vector<int> height(n, 0), left(n, 0), right(n, n);
        for(int i = 0; i < matrix.size(); ++i){
            int l = 0, r = n;
            for(int j = 0; j < n; ++j){
                if(matrix[i][j] == '1'){
                    ++height[j];
                    left[j] = max(left[j], l);
                } else {
                    l = j + 1;
                    height[j] = 0;
                    left[j] = 0;
                    right[j] = n;
                }
            }
            for(int j = n - 1; j >= 0; --j){
                if(matrix[i][j] == '1'){
                    right[j] = min(right[j], r);
                    res = max(res, height[j] * (right[j] - left[j]));
                } else {
                    r = j;
                }
            }
        }
        return res;
    }
};
原文地址:https://www.cnblogs.com/Atanisi/p/7559618.html