单调栈
单调栈可分为单调递增栈和单调递减栈
- 单调递增栈:栈中元素从栈底到栈顶递增。栈顶为最大元素。
- 单调递减栈:栈中元素从栈底到栈顶递减。栈顶为最小元素。
单调递增栈
记当前元素为xxx,栈顶元素为yyy。
对于一个数组中的元素,进行如下操作:
- x≥yx \geq yx≥y时,将xxx入栈
- x<yx < yx<y时,将yyy出栈,直到栈顶元素≤x\leq x≤x然后将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 yx≥y)。
所以,由一个单调递增栈,我们可以得到的结论是:
- 数组中栈顶元素右边小于该元素的的第一个数;即,当栈顶元素出栈时,当前元素为栈顶元素右边第一个小于栈顶元素的数。
- 数组中当前元素左边小于等于该元素的第一个数。当当前元素入栈时,栈顶元素为当前元素左边第一个小于等于该元素的数。
这里到底是小于还是小于等于,关键是看入栈/出栈的条件。如果出栈条件为x≤yx \leq yx≤y,也就是x=yx=yx=y时也要出栈,那么xxx为yyy右边第一个小于等于yyy的元素;如果出栈条件为x<yx<yx<y,那么xxx为yyy右边第一个小于该元素的数。
如果我们调整一下入栈的条件,修改为:
记当前元素为xxx,栈顶元素为yyy。
对于一个数组中的元素,进行如下操作:
- x>yx > yx>y时,将xxx入栈
- x≤yx \leq yx≤y时,将yyy出栈,直到栈顶元素y<xy < xy<x然后将xxx入栈。当栈顶元素y≥xy \geq xy≥x当前元素时,进行弹栈操作。
那么可以得到结论:
- 数组中栈顶元素右边小于等于该元素的的第一个数;
- 数组中当前元素左边小于该元素的第一个数。
单调递减栈
对于单调递减栈,只需要将上述结论中的小于改成大于即可。
单调递减栈结论:
- 数组中栈顶元素右边**大于(等于)**该元素的的第一个数;
- 数组中当前元素左边**大于等于(大于)**该元素的第一个数。
本文介绍了单调栈的概念,包括单调递增栈和单调递减栈。单调递增栈保证了栈内元素从栈底到栈顶递增,反之则递减。通过举例和详细解释入栈和出栈条件,阐述了单调栈如何找到数组中元素右边第一个小于或等于它的数,以及左边第一个小于等于它的数。单调递减栈的结论与递增栈类似,只需将比较关系调整为大于。

509

被折叠的 条评论
为什么被折叠?



