基础算法-单调栈

本文介绍了单调栈的概念,包括单调递增栈和单调递减栈。单调递增栈保证了栈内元素从栈底到栈顶递增,反之则递减。通过举例和详细解释入栈和出栈条件,阐述了单调栈如何找到数组中元素右边第一个小于或等于它的数,以及左边第一个小于等于它的数。单调递减栈的结论与递增栈类似,只需将比较关系调整为大于。

单调栈

单调栈可分为单调递增栈和单调递减栈

  • 单调递增栈:栈中元素从栈底到栈顶递增。栈顶为最大元素。
  • 单调递减栈:栈中元素从栈底到栈顶递减。栈顶为最小元素。

单调递增栈

记当前元素为xxx,栈顶元素为yyy

对于一个数组中的元素,进行如下操作

  • x≥yx \geq yxy时,将xxx入栈
  • x<yx < yx<y时,将yyy出栈,直到栈顶元素≤x\leq xx然后将xxx入栈。当栈顶元素>>>当前元素时,进行弹栈操作。

这样就维护了一个单调递增栈。

维护这样一个栈有什么意义呢,我们看一个例子:3,1,4,5,2,73, 1, 4, 5, 2, 73,1,4,5,2,7

x=2x = 2x=2时,栈中元素为1,4,5,y=51, 4, 5,y=51,4,5,y=5。我们要将2入栈,则需要将4 5依次出栈,最终得到1,21, 21,2

那么这里出栈的4,54, 54,5分别代表着什么?仔细观察可以发现,2是5右边第一个小于5的元素,同样的,2也是4右边第一个比它小的数。按照操作中的第二条,当栈顶元素被弹出时,意味着当前元素是栈顶元素右边第一个比它小的数

类似地,我们思考一下这一步形成的最终序列1,21,21,2。1对2来说意味着什么?显然,1是2左边第一个小于等于2的元素(请注意这里用的小于等于,原因是在 操作①中,入栈的条件是x≥yx \geq yxy)。

所以,由一个单调递增栈,我们可以得到的结论是:

  • 数组中栈顶元素右边小于该元素的的第一个数;即,当栈顶元素出栈时,当前元素为栈顶元素右边第一个小于栈顶元素的数。
  • 数组中当前元素左边小于等于该元素的第一个数。当当前元素入栈时,栈顶元素为当前元素左边第一个小于等于该元素的数。

这里到底是小于还是小于等于,关键是看入栈/出栈的条件。如果出栈条件为x≤yx \leq yxy,也就是x=yx=yx=y时也要出栈,那么xxxyyy右边第一个小于等于yyy的元素;如果出栈条件为x<yx<yx<y,那么xxxyyy右边第一个小于该元素的数。

如果我们调整一下入栈的条件,修改为:

记当前元素为xxx,栈顶元素为yyy

对于一个数组中的元素,进行如下操作

  • x>yx > yx>y时,将xxx入栈
  • x≤yx \leq yxy时,将yyy出栈,直到栈顶元素y<xy < xy<x然后将xxx入栈。当栈顶元素y≥xy \geq xyx当前元素时,进行弹栈操作。

那么可以得到结论

  • 数组中栈顶元素右边小于等于该元素的的第一个数;
  • 数组中当前元素左边小于该元素的第一个数。

单调递减栈

对于单调递减栈,只需要将上述结论中的小于改成大于即可。

单调递减栈结论

  • 数组中栈顶元素右边**大于(等于)**该元素的的第一个数;
  • 数组中当前元素左边**大于等于(大于)**该元素的第一个数。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值