单调栈

单调栈
一个单调递增(递减)的栈。在题目应用中主要是对栈的维护,通过判断和出入栈操作对栈进行维护,使之保持单调的状态。

维护
判断栈顶元素与数组元素的大小,如果 栈顶元素 < 数组元素 使栈顶元素出栈,如果 栈顶元素 > 数组元素 使数组元素入栈。

一个单调递减栈的例子:
进栈元素分别为3,4,2,6,4,5,2,3
3进栈:(3)
3出栈,4进栈:(4)
2进栈:(4,2)
2出栈,4出栈,6进栈:(6)
4进栈:(6,4)
4出栈,5进栈:(6,5)
2进栈:(6,5,2)
2出栈,3进栈:(6,5,3)

直方图是由在公共基线处对齐的一系列矩形组成的多边形。
矩形具有相等的宽度,但可以具有不同的高度。
例如,图例左侧显示了由高度为2,1,4,5,1,3,3的矩形组成的直方图,矩形的宽度都为1:
在这里插入图片描述
题目——直方图中的最大矩形
通常,直方图用于表示离散分布,例如,文本中字符的频率。
现在,请你计算在公共基线处对齐的直方图中最大矩形的面积。
图例右图显示了所描绘直方图的最大对齐矩形。
输入格式
输入包含几个测试用例。
每个测试用例占据一行,用以描述一个直方图,并以整数n开始,表示组成直方图的矩形数目。
然后跟随n个整数h1,…,hn。
这些数字以从左到右的顺序表示直方图的各个矩形的高度。
每个矩形的宽度为1。
同行数字用空格隔开。
当输入用例为n=0时,结束输入,且该用例不用考虑。
输出格式
对于每一个测试用例,输出一个整数,代表指定直方图中最大矩形的区域面积。
每个数据占一行。
请注意,此矩形必须在公共基线处对齐。
数据范围
1≤n≤100000,
0≤hi≤1000000000
输入样例:
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0
输出样例:
8
4000

初始化三个数组

int a[100010];
int stack[100010];//栈
int l[100010];//记录当前的长度

从第一个元素开始判断,如果数组元素大于栈顶元素就入栈,并把当前长度记录为1;

int j=0;
if(a[i]>stack[j])
{
  stack[++j]=a[i];
  l[j]=1;
 }

如果没有达到入栈要求,就挨个出栈,直到再次满足入栈要求。每出栈一次就计算一次面积,并进行判断,保留最大值。

int ans=0;//初始化
int len=0;
long long int S;
while(stack[j]>a[i])
{
  len+=l[j];
 S=(long long int)len*stack[j];//因为len和stack[]都是int,但结果会爆int
  if(S>ans)//判断大小,保留最大面积
  ans=S;
  j--;//出栈操作
}

出栈完之后达到入栈要求(单调递增),将数组元素入栈,并记录len,方便下次使用。

stack[++j]=a[i];//达到入栈要求,将数组元素入栈
l[j]=len+1;//记录长度

最后就输出结果就可以了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值