每天学一丢之 单调栈

本文详细介绍了单调栈的概念,其核心在于维护一个单调性的数据结构,以实现高效查找序列中某个元素左侧第一个比它大的数。通过单调栈,可以在O(n)的时间复杂度内完成这一任务,特别适用于处理序列中的单调性问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

每天学一丢意为每天学一点丢一点。

单调栈

单调栈即我们在维护栈时,同时让栈里的元素维持着单调性。即当我们维护一个单调上升的栈时,如果需要入栈一个新元素后,如果这个元素之前有比他大的值,破坏了栈内元素的单调性,我们就要把比它大的值全部出栈,此时再将新元素入栈,来保证栈内元素的单调性。单调是说栈内元素具有单调性,

功能

利用单调栈,我们可以在 O(n)O(n)O(n) 的时间复杂度内,维护序列中任意一个数,向左遍历时,第一个比它大的数,同理可以改变方向和大小关系。

思路

如果我们想要找一个数,它左侧比它大的第一个数,我们需要维护一个单调递减的栈。假设栈内元素从栈底到栈顶分别为 x1  x2  x3x_1\; x_2\; x_3x1x2x3,因为是一个单调递减的栈,我们知道如果 x3x_3x3 比新入栈元素 kkk 要小的话会直接出栈,那么直到遇到第一个比 kkk 大的栈内元素,假设为 x2x_2x2 时才会停下,此时栈顶元素 x2x_2x2 就是 kkk左侧第一个比kkk大的数。对于栈内已有的 x1  x2  x3x_1\; x_2\; x_3x1x2x3 三个数字这样一定是正确的,但是我们在维护栈时有许多删去的数字,如何证明这种删去是不会影响最后结果的。我们假设 x2,  x3x_2,\; x_3x2,x3 中间省略了三个值,那么省略的原因是,这些值同时小于x2,  x3x_2,\; x_3x2,x3,那么当 x3x_3x3 需要出栈时,这些值也都是需要出栈的,所以不会影响结果

代码

给出一段用数组模拟栈的代码,因为数组可以更好的访问栈内元素,也可以进行二分操作等。

top = 0;
rep(i, 1, n+1){
	while(top && num[s[top-1]]>=num[i]) 
		top--;
	l[i] = top?s[top-1]:0;
	s[top++] = i;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值