[Leetcode 85] Maximal Rectangle

  • Question
    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,求柱状图中最大矩阵的面积。
      例如:
      左边是原始矩阵, 右边对应转换后的柱状图,(行与行对应,相应位置的数表示该位置的高度)
      
      1 0 1 0 0    ----->      1 0 1 0 0
      1 0 1 1 1    ----->      2 0 2 1 1
      1 1 1 1 1    ----->      3 0 3 2 2 
      1 0 0 1 0    ----->      4 0 0 3 0 

    代码如下:

class Solution {
public:
    int largestRectangleArea(const vector<int>& bar){
        int ret=0;
        int len=bar.size();
        stack<int> s;
        for(int i=0; i<len;++i){
            while(!s.empty() && bar[s.top()] > bar[i]){
                int h=bar[s.top()];
                s.pop();
                int left=s.empty()?-1:s.top();

                if(ret<(i-left-1)*h) ret=h*(i-left-1);
            }
            s.push(i);
        }
        return ret;
    }
    int maximalRectangle(vector<vector<char>>& matrix) {
        if(matrix.empty()) return 0;
        int maxA=0;
        int row=matrix.size(), col=matrix[0].size();
        vector<int> bar(col+1,0);
        for(int i=0; i<row; ++i){
            for(int j=0; j<col; ++j){
                if(matrix[i][j]=='1') ++bar[j];
                else bar[j]=0;
            }
            maxA=max(maxA,largestRectangleArea(bar));
        }
        return maxA;
    }
};
  • 动态规划解法(详见这里)。 点(i, j) 所在的矩阵的面积为height[i, j]*(right[i, j]-left[i, j])。其中height[i, j]统计当前位置及往上’1’的数量;left和right是高度是当前点的height值得左右边界。
    转化方程如下:
left(i,j) = max(left(i-1,j), cur_left),   

right(i,j) = min(right(i-1,j), cur_right)  

height(i,j) = height(i-1,j) + 1, if matrix[i][j]=='1';    

height(i,j) = 0, if matrix[i][j]=='0'

代码如下:

 int maximalRectangle(vector<vector<char>>& matrix) {
        if(matrix.empty()) return 0;
        int maxA=0;
        int row=matrix.size(), col=matrix[0].size();
        vector<int> left(col,0),height(col,0), right(col,col);

        for(int i=0; i<row; ++i){
            int curleft=0,curright=col;
            for(int j=0; j<col; ++j){
                if(matrix[i][j]=='1') height[j]=++height[j];
                else height[j]=0;

                if(matrix[i][j]=='1') left[j]=max(left[j],curleft);
                else{
                    left[j]=0;curleft=j+1;
                }
            }

            for(int j=col-1; j>=0; --j){
                if(matrix[i][j]=='1') right[j]=min(right[j],curright);
                else{
                    right[j]=col; curright=j;
                }
            }

            for(int j=0; j<col;++j)
                maxA=max(maxA,(right[j]-left[j])*height[j]);
        }
        return maxA;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值