cf上的1886C
从第一个字符开始往后,删除第一对第一个字符大于第二个字符的相邻字符组中的第一个字符。还没找到就一直入栈,当即将入栈元素和栈顶元素满足上述条件时,栈顶元素出栈,继续判断,直到待入元素满足入栈条件。(每一次有元素出栈,要执行一次查询位置减字符串长度,字符串长度减一)
单调栈
单调栈就是维护一个单调递增或者单调递减的栈,将时间复杂度降为O(n)
栈空或栈顶元素更优时元素入栈(老人仍然比新人强)
else 栈顶元素出栈(新人比老人年轻还比老人强)
单调栈一般用于解决一下几种问题:
-
寻找左侧第一个比当前元素大的元素。
-
寻找左侧第一个比当前元素小的元素。
-
寻找右侧第一个比当前元素大的元素。
-
寻找右侧第一个比当前元素小的元素。
1.寻找左侧第一个比当前元素大的元素
从左到右遍历元素,构造单调递增栈(从栈顶到栈底递增):
一个元素左侧第一个比它大的元素就是将其「插入单调递增栈」时的栈顶元素。
如果插入时的栈为空,则说明左侧不存在比当前元素大的元素。
2.寻找左侧第一个比当前元素小的元素
从左到右遍历元素,构造单调递减栈(从栈顶到栈底递减):
一个元素左侧第一个比它小的元素就是将其「插入单调递减栈」时的栈顶元素。
如果插入时的栈为空,则说明左侧不存在比当前元素小的元素。
3.寻找右侧第一个比当前元素大的元素
从左到右遍历元素,构造单调递增栈(从栈顶到栈底递增):
一个元素右侧第一个比它大的元素就是将其「弹出单调递增栈」时即将插入的元素。
如果该元素没有被弹出栈,则说明右侧不存在比当前元素大的元素。
从右到左遍历元素,构造单调递增栈(从栈顶到栈底递增):
一个元素右侧第一个比它大的元素就是将其「插入单调递增栈」时的栈顶元素。
如果插入时的栈为空,则说明右侧不存在比当前元素大的元素。
4.寻找右侧第一个比当前元素小的元素
从左到右遍历元素,构造单调递减栈(从栈顶到栈底递减):
一个元素右侧第一个比它小的元素就是将其「弹出单调递减栈」时即将插入的元素。
如果该元素没有被弹出栈,则说明右侧不存在比当前元素小的元素。
从右到左遍历元素,构造单调递减栈(从栈顶到栈底递减):
一个元素右侧第一个比它小的元素就是将其「插入单调递减栈」时的栈顶元素。
如果插入时的栈为空,则说明右侧不存在比当前元素小的元素。
上边的分类解法有点绕口,可以简单记为以下条规则:
无论哪种题型,都建议从左到右遍历元素。
查找 「比当前元素大的元素」 就用 单调递增栈,查找 「比当前元素小的元素」 就用 单调递减栈。
从 「左侧」 查找就看 「插入栈」 时的栈顶元素,从 「右侧」 查找就看 「弹出栈」 时即将插入的元素。