[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.

For example,
Given heights = [2,1,5,6,2,3],
return 10.

寻找柱状图中的最大矩形,给出的是柱状图的一系列高度值,每个值对应的水平宽度为1。
显然,可以通过暴力方法求解这个题,也即是,每次求出区间[i,j]的最小值,然后乘以对应宽度,得到当前[i,j]内的矩形面积,但这样的时间复杂度为o(n^2),会超时

一个比较巧妙的办法是借助栈实现,思路描述如下:
在栈index中,依次保存使得高度升序的一系列索引值,
1. 当前索引值为i时,如果当前i对应的高度大于index栈顶对应的高度,则将i索引push进栈中,
2. 如果当前i的高度是小于栈顶高度,则将栈顶元素pop出来,并计算栈顶(下一个)索引和i之间的矩形面积
这样,时间复杂度为o(n)

注释1:一个问题是,为什么可以这样呢?嗯,仔细思考一下,实际上,当我们进行pop操作时,取出来的高度就是下一栈顶和当前i之间的最小高度值(注意不包括栈顶和i,是开区间),因为凡是比当前高度大的值,在pop出当前高度的时候,就已经被pop出来了(因为栈内始终是升序呀),这样也就计算出了一系列矩形面积值。

注释2:另外,这种优化也是十分巧妙的,因为它避免了大量重复的运算,当一个序列为递增序列时,例如{1,2,3,4},如果我们采用暴力方法计算时,对于任意区间[i,j],因为首元素始终是最小的,所以后续一系列区间(增加j时)的计算其实都是没有必要的,但是利用栈,将这种计算延后(实际上也通过栈来帮助我们识别出这种单调性),每次pop出的时候再计算,简化了一系列重复计算的步骤。

注释3:单调栈

class Solution {
public:
    int largestRectangleArea(vector<int>& heights) {
        heights.push_back(0);
        int n=heights.size(),i=0,maxArea=0;
        stack<int> index;
        while(i<n){
            if(index.empty()||heights[i]>=heights[index.top()])
                index.push(i++);
            else{
                int tp=index.top();
                index.pop();
                maxArea=max(maxArea,heights[tp]*(index.empty()?i:i-index.top()-1));
            }
        }
        return maxArea;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值