algorithm: 柱状图中最大的矩形

84. 柱状图中最大的矩形

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3]。
图中阴影部分为所能勾勒出的最大矩形面积,其面积为 10 个单位。
示例:
输入: [2,1,5,6,2,3]
输出: 10

在这里插入图片描述
在这里插入图片描述
这道题有多种解法,这里主要介绍用单调栈的解法。
分析这道题:常见思路就是遍历,看每个柱子能参与围成的最大矩形面积,即找到当前柱子左右大于等于它的柱子数,即大于等于当前柱子的左右边界

  • 面 积 = ( 右 边 界 − 左 边 界 ) ∗ 当 前 柱 子 高 度 面积=(右边界-左边界)*当前柱子高度 =()

那问题是如何确定大于等于当前柱子的左右边界呢?
根据这个思路,单调栈十分适合这个思路。

  • 1.单调栈分为递增或递减栈
  • 2.如果是递增栈,如果栈顶元素小于等于新元素,直接插入;如果栈顶元素大于新元素i,则执行出栈操作(通过在末尾添加0,保证每个元素都会进行入栈出栈),出栈时会计算当前柱子构建的面积,面积=(右边界-左边界)*当前柱子高度,右边界为i,左边界为栈顶元素前一个元素。
    例如[2,1,5,6,2,3],末尾添加元素0,[2,1,5,6,2,3,0]栈的变化如下
    [0] 元素0入栈
    [] 由于2>1,所以执行出栈并计算面积 2 ∗ ( 1 − 0 ) 2*(1-0) 2(10),然后元素1的索引入栈
    [1,2]元素5的索引入栈
    [1,2,3]元素6的索引入栈
    [1,2]由于6>2,所以6出栈并计算面积;由于5大于2,所以5继续出栈并计算面积
    [1,4]
    [1,4,5]
    [1,4]这里遍历到我们增加的元素0,所以执行出栈,这样所有元素执行出栈。

注意:

  • 如果是相邻的相同元素,实际以前面的元素面积为准,不过最后取的都是最大值,这里没有影响。
  • 当计算面积时当前为空栈,表示前面的元素都大于栈顶元素,所以计算面积时左边界从索引0开始
  • 出栈的截止条件是栈顶元素大于等于遍历到的元素

代码如下

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        heights.push_back(0);
        int maxval = 0;
        stack<int> stk;
        for(int i=0;i<heights.size();i++){
            while(!stk.empty()&&heights[i]<heights[stk.top()]){
                int top = stk.top();
                stk.pop();
                maxval = max(maxval,heights[top]*(stk.empty()? i: i-stk.top()-1));
            }
            stk.push(i);
        }
        return maxval;
    }
};

int main(){
    vector<int> heights = {2,1,3,4,5};
    int res = Solution().largestRectangleArea(heights);
    cout<<res<<endl;
}

其实我觉得最精髓的是出栈的控制,执行流程已经看懂,后续慢慢体会~

参考
84. 柱状图中最大的矩形/C++
84. 柱状图中最大的矩形

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值