力扣LCR 039. 柱状图中最大的矩形

思路
用到了单调栈。由于最大矩形它的高一定是height数组中的其中一个值,那么我们就可以遍历数组height的值再乘上它的宽的最大值WidthMax(宽的最大值后面会讲),然后取最大值就是答案,也就是ans=max(ans,WidthMax*height[x])。
那么如何求高为height[x]的宽的最大值WidthMax呢?
解题过程

如图,以黄色块为高所能撑起的最大范围即为红色部分,(数组heigh中的每个值都有可能是黄色块,所以后面要遍历一下)那么问题就转变为:
1.求从x开始的左边找第一个高度小于heigh[x]的长方形的下标l
2.同理,求从x的右边第一个小于heigh[x]的长方形的下标r
3.矩形的宽的最大值为WidhMax = r -l -1

那么问题又转变为如何求上面的l和r?
对于求r,此问题不就是已知数组的下标,求该下标开始从右边开始找第一个更小值吗?此时就可以用单调栈的思想来预处理每个点的右边界的值了,该过程与力扣中https://leetcode.cn/problems/next-greater-element-i/description/这道题相似,不懂单调栈的可以先做那道题
那么l也同理,从左边开始找第一个更小值的下标
那么r[x]和l[x]就求出来了,
最后遍历每个小长方形,求(height[x]*(r[x]-l[x]-1))的最大值就是答案了

时间复杂度: 𝑂(𝑛)
空间复杂度: 𝑂(𝑛)

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        //选定一个下标,从这个下标两边分别找第一个比它矮的下标(理解为找左边的第一个更小数,右边的第一个更小数),然后r-l-1个这样的矩形的和即为答案的可能之一
        const int N = 1e5+50;
        int l[N], r[N], s[N],top = -1;
        //预处理每个点的两边第一次碰到更矮的下标
        for(int i = 0; i < heights.size(); i++){
            int num = heights[i];
            while(top>=0&&heights[s[top]]>=num){
                top--;
            }
            if(top>=0)
                l[i] = s[top];
            else l[i] = -1;
            s[++top]=i;
        }
        top = -1;
        for(int i = heights.size()-1; i >= 0; i--){
            int num = heights[i];
            while(top>=0 && heights[s[top]] >= num)
                top--;
            if(top>=0) r[i] = s[top];
            else r[i] = heights.size();
            s[++top] = i;
        }
        int ans = 0;
        for(int i = 0; i < heights.size(); i++){
            ans = max(ans,(r[i]-l[i]-1)*heights[i]);
        }
        return ans;
    }
};

posted @   binbin成长日记  阅读(7)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示