每天学一丢之 单调栈

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

单调栈

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

功能

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

思路

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

代码

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

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值