131.直方图中最大矩形

文章讲述了如何使用单调栈来解决直方图中最大矩形面积的问题,通过遍历和栈的操作找到每个矩形能扩展的最大边界,最后求得所有可能的最大面积。
摘要由CSDN通过智能技术生成

直方图是由在公共基线处对齐的一系列矩形组成的多边形。

矩形具有相等的宽度,但可以具有不同的高度。

例如,图例左侧显示了由高度为 2,1,4,5,1,3,32,1,4,5,1,3,3 的矩形组成的直方图,矩形的宽度都为 11:

2559_1.jpg

通常,直方图用于表示离散分布,例如,文本中字符的频率。

现在,请你计算在公共基线处对齐的直方图中最大矩形的面积。

图例右图显示了所描绘直方图的最大对齐矩形。

思路如下

遍历每个矩形将其向左右伸展直到左右高度都小于当前高度,此为当前矩形最大面积。求出所有遍历面积中最大面积。

知识点及其实现

单调栈

依次将每一个高度读入栈中,每次进行遍历的时候当遇到左边高度大于当前高度时就将栈尾删去(因为当下一次遍历的时候无论其高度多少都不会用到这个元素)。

用单调栈有这个好处:这个维护的是其q[i]始终是i的左边的最小高度的编号。

(疏于语言只能描述成这样)

以下为代码

#include <iostream>
#include <algorithm>
using namespace std;

typedef long long LL;
const int N = 1e5;
int n;
int q[N], h[N], l[N], r[N];
//单调栈的实现
void get(int a[N]){
    int tt = 0;
    for(int i = 1;i <= n;i ++){
      while(h[q[tt]] >= h[i])  tt --;
      a[i] = q[tt];
      q[++ tt] = i;
    }
}
int main(){
    h[0] = -1;
    while(cin >> n, n){
        for(int i = 1;i <= n;i ++) scanf("%d", &h[i]);
        get(l);
        reverse(h + 1, h + n + 1);
        get(r);
        LL res = 0;
        for(int i = 1,j = n;i <= n;i ++,j --){
            res = max(res, h[i] * (n + 1 - l[j] - r[i] - 1ll));//小难点reverse后下标i转换成n — i + 1而r[i]于l[n - 1 + 1]对应即
                                                              //要转换两次
        }
        cout << res << endl;
    }
    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值