栈:直方图中最大的矩形

题目链接:https://www.acwing.com/problem/content/133/
题意:直方图是由在公共基线处对齐的一系列矩形组成的多边形。
矩形具有相等的宽度,但可以具有不同的高度。
例如,图例左侧显示了由高度为2,1,4,5,1,3,3的矩形组成的直方图,矩形的宽度都为1:
在这里插入图片描述
通常,直方图用于表示离散分布,例如,文本中字符的频率。
现在,请你计算在公共基线处对齐的直方图中最大矩形的面积。图例右图显示了所描绘直方图的最大对齐矩形。
数据范围
1≤n≤100000,
0≤hi≤1000000000
输入样例:
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0
输出样例:
8
4000
思路:其实不难发现对于第i个小矩形,只要找到左边第一个小于它的小矩形lefti,和右边第一个比它小的小矩形righti,那么以第i个小矩形为顶边的最大矩形面积为(righti - lefti - 1) * 宽;而关于第一个小于它的数怎么找最快,就可以想到之前做过的单调队列啦,在寻找左边第一个小于它的数时,左边的数严格满足递增趋势(可回顾单调队列的博客)。
代码实现:

#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>

using namespace std;
typedef long long ll;
const int N = 1e5 + 5;

int n;
int h[N], q[N], l[N], r[N];

void get(int bound[N])
{
    int tt = 0;
    h[0] = -1;
    for(int i = 1; i <= n; i ++ ){
        while(h[q[tt]] >= h[i]) tt -- ;
        bound[i] = q[tt];
        q[ ++ tt] = i;
    }
}

int main()
{
    while(cin >> n, n){
        for(int i = 1; i <= n; i ++ )
            cin >> h[i];
        //立一个标兵在队头
        h[0] = -1;
        get(l);
        reverse(h + 1, h + n + 1);
        get(r);

        ll res = 0;
        //因为之前翻转了一下,所有原本的下标变成了对称位置的下标,1ll是long long 形式的1
        for(int i = 1, j = n; i <= n; i ++, j -- )
            res = max(res, h[i] * (n + 1 - l[j] - r[i] - 1ll));
        cout << res << endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值