leetcode【84】Largest Rectangle in Histogram

问题描述:

Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.

 


Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].

 


The largest rectangle is shown in the shaded area, which has area = 10 unit.

Example:

Input: [2,1,5,6,2,3]
Output: 10

题目意思就是给定一个数组,数组中存着各个位置的高度,让求出最大矩形的面积

解题思路:

最初的想法是暴力解决,遍历到一个位置i的时候,以i为矩形的左边,找到矩阵的面积,若大于当前矩形面积,则替换。这样做虽然可以通过,但是时间复杂度太高,面试官也无法满足,于是就考虑用一种增量栈的方法。

增量栈,顾名思义就是保持栈中元素是增量的。步骤如下:

  • 若栈为空或者栈顶索引对应的元素比当前索引对应的元素小,则将当前元素的索引入栈;
  • 若栈不为空且栈顶索引对应的元素比当前索引对应的元素大,则一次出栈,直到栈顶索引对应的元素比当前索引对应的元素小。出栈的时候计算以栈顶索引对应的元素为高度的矩形面积,因为栈中索引对应的元素是递增的,所以矩形的宽度由当前元素的索引减去栈顶索引即可;
  • 遍历结束后若栈仍不为空,则一次弹出,并计算面积。

注意:

  1. (入栈出栈都是索引,为了方便计算宽度)
  2. 留意栈为空的情况,栈中的最后一个索引对应的元素比之前遍历的所有元素都小,此时直接用当前遍历的索引代替宽度。比如2,3,4,1。遍历到元素1(索引3)的时候会一直出栈到空,则以2为高度的矩形宽度直接用3.

样例为2 1 5 6 2 3

i=0:栈为0

i=1:栈输出0,result更新,输入1

i=2:栈为1 2

i=3:栈为1 2 3

i=4:栈依次输出3 2,并动态更新result,输入4

i=5:栈为1 4 5

栈依次输出5 4 1,并动态更新result

Tips:更新result是指比较原有result,与i的左边第一条的边作为矩形右边的边,栈顶的右边的第一条边作为矩形左边,而围城的矩形的面积(有点拗口,理解一下),当然要是此时栈为空,左边的边的序号就以0算。

代码:

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        stack<int> h;
        int result = 0;
        for(int i=0; i<heights.size(); i++){
            if(h.empty() || heights[i]>=heights[h.top()]){
                h.push(i);
            }
            else{
                while(!h.empty() && heights[i]<heights[h.top()]){
                    int tmp = heights[h.top()];
                    h.pop();
                    int tmpw = h.empty()?i:i-h.top()-1;
                    result = max(result, tmp*tmpw);
                }
                h.push(i);
            }
        }
        while(!h.empty()){
            int tmp = heights[h.top()];
            h.pop();
            int tmpw = h.empty()?heights.size():heights.size()-h.top()-1;
            // cout<<tmp<<" "<<tmpw<<endl;
            result = max(result, tmp*tmpw);
        }
        return result;
    }
};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值