单调栈\单调队列


偶然想起单调栈和单调队列的知识点,就想把它记录下来

单调栈和单调队列都是维护一个容器内元素的单调性/滑窗是单调队列的推广这里不细说了,会滑窗一定会单调队列

单调栈可以获取从当前元素起,左边第一个比自己大的元素或者比自己小的元素,右边对称同理。来看一道最长子序列上升的题。

 1 class Solution {
 2 public:
 3     int lengthOfLIS(vector<int>& nums) {
 4         int n=nums.size(),top=0;
 5         int st[n+1];
 6         for(int i=0;i)
 7         {
 8             if(!top||st[top-1]nums[i];
 9             else
10             {
11                 int t=lower_bound(st,st+top,nums[i])-st;
12                 st[t]=nums[i];
13             }
14         }
15         return top;
16     }
17 };

对于当前元素和栈顶元素比较,如果当前元素大于栈顶元素,压栈更新最长子序列

如果小于等于栈顶元素,我们可以从栈里找第一个>=当前元素的元素a[i],把它替换

替换后i之前的所有子序列长度不会改变,而对于与替换的a[j]来说,以a[j]结尾的最长子序列和以a[i]的相同,而且对于未来的元素,a[i]比a[j]小

所以a[i]更优。即如果未来需要从a[j]结尾的长度更新,那么a[i]是较优的,基于这种替换规则我们能证明算法的正确性;

相关