单调栈模板

单调栈

顾名思义就是栈里的元素是单调的。

但是这个怎么使用呢?怎么就能是单调的呢?看下面的例题

题目
给定一个长度为N的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出-1
输入样例:

5
3 4 2 7 5

输出样例:

-1 3 -1 2 2

题目意思很容易理解
那么我们先来看暴力做法,每次取一个数,与前面的数比较

for(int i=0;i<n;i++{
	for(int j=1;j=i;j++)
	{
		if(a[j]>=a[j-1])
		{
			break;
		}
	}
}

我们考虑最坏的情况,当序列为降序序列时,例如:

5
5 4 3 2 1

5的话不进循环
4的话与5比较
3与4和5比较
2与3、4和5进行比较
1与2、3、4和5进行比较

观察我们可以发现,我们就需要取出每个数,然后遍历一遍这个数之前的所有数。
时间复杂度为O(n^2),oj数据范围都是n<=1e5,评测机1s内运算数据量是1e8~1e9,我们对1e10的数据量是不能接受的,因此我们需要对做法进行优化。这个时候我们就引入单调栈。

以输入样例为例来模拟一下单调栈
3 4 2 7 5

我们顺序遍历,从前往后看

先看3,前面没有比他小的放入栈中
再看4,然后与栈顶元素比较,发现满足条件,那么输出栈顶元素,然后将4入栈
再看2,同样与栈顶元素比较,但是栈顶元素比2大,那么我们就需要pop出栈,然后再与栈顶元素比较,直到找到比2小的元素,或者是栈空时结束,然后我们需要判断栈是否为空,栈空就输出-1,栈不空那么就说明找到了比2小的元素,即输出栈顶元素,最后将2入栈
再看7,比较栈顶元素,小于栈顶元素,那么输入栈顶元素,入栈
最后看5,比较弹出栈顶元素,然后再比较,发现满足条件,输出栈顶元素

我们再看一下栈中元素的变化过程
3
3 4
2
2 7
2 5

这个时候就会发现栈中的元素是从栈底到栈顶是单调递增的。这也就是为什么叫做单调栈!!!

模板代码

#include<iostream>
using namespace std;
const int N=1e5+5;
int a[N],stk[N],n,tt=0;
int main()
{
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d",a+i);
    for(int i=0;i<n;i++)
    {
        while(tt&&a[i]<=stk[tt]) --tt;
        if(tt) printf("%d ",stk[tt]);
        else printf("-1 ");
        stk[++tt]=a[i];
    }
    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值