85. 最大矩形

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

示例:

输入:
[
  ["1","0","1","0","0"],
  ["1","0","1","1","1"],
  ["1","1","1","1","1"],
  ["1","0","0","1","0"]
]
输出: 6

方法1:暴力求解

class Solution {
public:
    int help(int i, int j, vector<vector<char>>& matrix){
        int re = 0, w = matrix[0].size();
        for (int p = i; p<matrix.size(); ++p){
            for (int q = j; q<w; ++q){
                if (matrix[p][q] == '0' && q<matrix[0].size()){
                    w = q;
                    re = max(re, (q - j)*(p - i + 1));
                }
                if (matrix[p][q] == '1' && q == w - 1){
                    re = max(re, (w - j)*(p - i + 1));
                }
            }
        }
        return re;
    }

    int maximalRectangle(vector<vector<char>>& matrix) {
        int re = 0;
        for (int i = 0; i<matrix.size(); ++i){
            for (int j = 0; j<matrix[0].size(); ++j){
                if (matrix[i][j] == '1')
                    re = max(re, help(i, j, matrix));
            }
        }
        return re;
    }
};

方法2:借用84. 柱状图中最大的矩形的思路,二维矩阵每一层向上都可以看做一个直方图,输入矩阵有多少行,就可以形成多少个直方图。设置一个高度数组,如果当前行值为1的话,高度在原来基础上加1,否则置为0。求高度过程中采用了动态规划的思想。

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int re = 0;
        vector<int> s;
        heights.push_back(0);//加上这个,可以少写最后一段,很简洁
        for (int i = 0; i<heights.size(); ++i){
            while (!s.empty() && heights[s.back()]>heights[i]){
                int h = heights[s.back()];
                s.pop_back();
                int temp = s.size() ? h * i : h * (i - s.back());
                re = max(re, temp);
            }
            s.push_back(i);
        }
        return re;
    }

    int maximalRectangle(vector<vector<char>>& matrix) {
        if(matrix.empty() || matrix[0].empty()) return 0;
        int re = 0;
        vector<int> heights(matrix[0].size(), 0);
        for (int i = 0; i<matrix.size(); ++i){
            for (int j = 0; j<matrix[0].size(); ++j){
                matrix[i][j] == '1' ? heights[j]++ : heights[j]=0;
            }
            re=max(re, largestRectangleArea(heights));
        }
        return re;
    }
};

方法3:方法1暴力求解,之前的行和列的结果都没利用上。方法2中,用上了之前每一列的结果,行的结果没用上。方法3是最好的,之前的行和列的结果都利用上了。新建两个数组left和right分别表示构成的矩形的左边界和右边界的位置,新建两个变量cur_left, cur_right分别表示当前行左边界和右边界的位置。左边界存与该元素相连的最左端的1的位置,右边界存与该元素相连的最右端的1的位置的下一个位置(方便计算)。如果当前元素是‘0’的话,那么左边界就是0,右边界就是n。O(n*m)的时间复杂度。

1、当matrix[i][j] == '1'时:

(1)cur_left, cur_right就为之前的值。

(2)heights[j]++

(3)left(i,j) = max(left(i-1,j), cur_left),right(i,j) = min(right(i-1,j), cur_right)

2、当matrix[i][j] == '0'时:

(1)cur_left变成j+1,cur_right就为j

(2)heights[j]=0

(3)left(i,j) =0,right(i,j) =n.

3、cur_left从左往右遍历,cur_right从右往左遍历

class Solution {
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        if(matrix.empty() || matrix[0].empty()) return 0;
        int re = 0, n=matrix[0].size();
        vector<int> pri(n, 0), left(n, 0), right(n, n);
        for (int i = 0; i<matrix.size(); ++i){
            int cur_left=0, cur_right=n;
            for (int j = 0; j<n; ++j){
                if(matrix[i][j] == '1'){
                    pri[j]++;
                    left[j]=max(left[j], cur_left);
                }
                else{
                    left[j]=0;
                    cur_left=j+1;
                    pri[j]=0;
                }
            }
            for(int j=n-1; j>=0; --j){
                if(matrix[i][j] == '1'){
                    right[j]=min(right[j], cur_right);
                }
                else {
                    right[j]=n;
                    cur_right=j;
                }
                re=max(re, pri[j]*(right[j]-left[j]));
            }
        }
        return re;
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值