131.直方图中最大矩形

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

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

例如,图例左侧显示了由高度为 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;
    }
    
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值