【LeetCode】84. 柱状图中最大的矩形

题目描述

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

                           

以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]

                               

图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。

示例:

输入: [2,1,5,6,2,3]
输出: 10

 

思路

利用栈将原图转化为递增序列,如将 215623 变为 112223,具体变化方法为:

栈为空时入栈,此时栈中只有 2,第二个数为 1,因为栈顶元素 2 > 1,所以将 2 弹出栈,计算此时最大的面积 2 * 1 = 2 存入 res,将 2 个 1 压入栈中,栈内元素为 [ 1 , 1 ] ,res = 2;

此时 heights[ i ] = 5 和 6,均大于栈顶元素 1,入栈,此时栈内元素为 [ 1 , 1 , 5 , 6 ];

此时 heights[ i ] = 2,因为 6 > 2,6 出栈,res = 6;

同理,5 出栈,res = 5 * 2 = 10(先出栈的一定大);

此时栈顶元素 1 < 2,结束 while 循环,将 3 个 2 压入栈中,栈内元素为 [ 1 , 1 , 2 , 2 , 2 ],res = 10;

此时 heights[ i ] = 3,3 > 2,3 入栈,栈内元素为 [ 1 , 1 , 2 , 2 , 2 , 3 ],res = 10。

对于栈 s,再求该图的最大矩形,与上面的 res 取最大值即可。

 

代码

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        int n = heights.size();
        stack<int> s;
        int res = 0;
        for(int i=0; i<n; i++){
            if(!s.empty() && s.top() > heights[i]){
                int len = 0;
                while(s.top() > heights[i]){
                    int temp = s.top();
                    s.pop();
                    len++;
                    res = max(res, len*temp);
                    //第一个元素出栈后栈为空,会报错
                    if(s.empty()) 
                        break;
                }
                for(int j=0; j<=len; j++){
                    s.push(heights[i]);
                }
            }else{
                s.push(heights[i]);
            }
        }
        //以下为对递增序列求最大值    
        int len = 0;
        int k = 0;
        while(!s.empty()){
            int temp = s.top();
            s.pop();
            len++;
            if(s.empty()){
                res = max(res, temp*n);
                return res;
            } 
            if(s.top() < temp){
                k += len;
                res = max(res, temp*k);
                len = 0;
            }        
        }
        return res;
    }
};

 

                     

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值