单调栈
去除重复字母
- 给你一个字符串
s
,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对位置)。
1 | string removeDuplicateLetters(string s) { |
接雨水
给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。
1 | // 暴力做法,直接搜索一个柱子两侧最高的柱,它的水平线一定是其中较矮的那个,这样每次左右分别搜索最高的柱子,一次搜索可以确定一个柱子上方的雨水量 |
132模式
132的结构中,2属于1,3之间,若要在1,3之间寻找2则需要维护多个区间,而1是最小的,如果可以维护一个尽量大的2,则可以方便的比较是否出现该结构。
则可从后往前遍历,同时使用单调栈来记录这样的性质。如果直接用单升栈是不能维护这样的性质的,因为我们需要一个尽量大的2,而不仅仅是一个单升的23性质。
因此可用单减栈,在遇到一个足够大的3时,2自然会弹出,而用一个变量记住弹出的最大的2即可。这样便维护了一个尽量大的2.
1 | bool find132pattern(vector<int>& nums) { |
单调队列
绝对差不超过限制的最长连续子数组
给你一个整数数组 nums ,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit 。
如果不存在满足条件的子数组,则返回 0 。
- 区间的任意两个数的绝对值差只与区间最小和最大有关,本题的思路就是滑动窗口维护这个区间,其中区间性质的关键是要找到最大值和最小值,可分别用单减队列和单增队列来找最大和最小,右边界在进入时需要维护单调队列,然后通过两个单调队列求出绝对差来判断是否满足条件,不满足条件则需要右移左边界,左边界移动的时候判断是否有最大或最小值移出,直到满足条件为止,然后继续移动右边界直到结束。
1 | int longestSubarray(vector<int>& nums, int limit) { |
1 | int longestSubarray(vector<int>& nums, int limit) { |