【ALGO】Leetcode 85.最大矩形

题面

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

解析

本题如果直接采用暴力枚举的解法,时间复杂度为 O ( n 6 ) \mathcal{O}(n^6) O(n6),考虑枚举下边界加预处理进行时间复杂度优化.
枚举第 i i i行,设第 i i i行第 j j j列的向上连续的1的个数为 f ( i , j ) f(i, j) f(i,j),则
f ( i , j ) = { 0 , m a t r i x ( i , j ) = 0 1 + f ( i − 1 , j ) , m a t r i x ( i , j ) = 1 f(i, j)= \begin{cases} 0, matrix(i, j)=0\\ 1+f(i-1, j), matrix(i, j)=1 \end{cases} f(i,j)={0,matrix(i,j)=01+f(i1,j),matrix(i,j)=1
然后问题可以转化为Leetcode 84.柱状图中最大矩形求解.

AC代码

class Solution {
private:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
        vector<int> left(n), right(n);
        stack<int> st; // 存储下标的单调栈

        // left->right sweep
        for(int i=0; i<n; ++i){
            while(!st.empty() && heights[st.top()]>=heights[i]) st.pop();
            if(st.empty()) left[i]=-1;
            else left[i]=st.top();
            st.push(i);
        }

        st = stack<int>();
        // right->left sweep
        for(int i=n-1; ~i; --i){
            while(!st.empty() && heights[st.top()]>=heights[i]) st.pop();
            if(st.empty()) right[i]=n;
            else right[i]=st.top();
            st.push(i);
        }

        int ans=0;
        for(int i=0; i<n; ++i){
            ans=max(ans, heights[i]*(right[i]-left[i]-1));
            // cout<<heights[i]<<" "<<left[i]<<" "<<right[i]<<endl;
        }

        return ans;
    }

public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        if(matrix.empty() || matrix[0].empty()) return 0;
        int n = matrix.size(), m=matrix[0].size();
        
        vector<vector<int>> f(n, vector<int>(m)); // 上方有多少个连续的1

        for(int i=0; i<n; ++i)
            for(int j=0; j<m; ++j){
                if(matrix[i][j]=='1' && i) f[i][j]=1+f[i-1][j];
                else if(matrix[i][j]=='1') f[i][j]=1;
                else f[i][j]=0;
            }

        int ans = 0;
        for(int i=0; i<n; ++i) ans=max(ans, largestRectangleArea(f[i])); // 枚举下边界
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

minuxAE

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值