单调队列
Posted aliencxl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单调队列相关的知识,希望对你有一定的参考价值。
参考文献:https://www.jianshu.com/p/e59d51e1eef5
单调队列,顾名思义,是一种具有单调性的队列。众所周知,单调性有单调递增和单调递减两种,相应的单调队列也分为单调递增队列和单调递减队列两种。
-
单调递增队列:保证队列头元素一定是当前队列的最小值,用于维护区间的最小值。
-
单调递减队列:保证队列头元素一定是当前队列的最大值,用于维护区间的最大值。
实现单调队列,主要分为三个部分:
- 去尾操作 :队尾元素出队列。当队列有新元素待入队,需要从队尾开始,删除影响队列单调性的元素,维护队列的单调性。(删除一个队尾元素后,就重新判断新的队尾元素)
去尾操作结束后,将该新元素入队列。
-
删头操作 :队头元素出队列。判断队头元素是否在待求解的区间之内,如果不在,就将其删除。(这个很好理解呀,因为单调队列的队头元素就是待求解区间的极值)
-
取解操作 :经过上面两个操作,取出 队列的头元素 ,就是 当前区间的极值 。
// 假设有 n 个元素的序列,要求解的是长度为 k 的区间的最大值 // 队列que是STL的双向队列deque // 队列存放的是元素在序列中的序号 deque<int>que;// 双向队列 for(int i=1;i<=n;i++) { while(!que.empty() && a[que.back()]<a[i]) { que.pop_back();// 去尾操作 } que.push_back(i);// 新元素(的序号) 入队列 if(i>=k)// 第k个元素之后才有区间 { while(!que.empty() && que.front()<i-k+1) { que.pop_front();// 删头操作 } cout<<a[que.front()]<<" ";// 取解操作 } }
64. 字符流中第一个只出现一次的字符
请实现一个函数用来找出字符流中第一个只出现一次的字符。
例如,当从字符流中只读出前两个字符”go”时,第一个只出现一次的字符是’g’。
当从该字符流中读出前六个字符”google”时,第一个只出现一次的字符是’l’。
如果当前字符流没有存在出现一次的字符,返回#字符。
class Solution{ public: unordered_map<char, int> count; queue<char> q; //Insert one char from stringstream void insert(char ch){ //不用去尾,因为前一个肯定比后一个先出现 q.push(ch); if (++ count[ch] > 1) { //去头 while (q.size() && count[q.front()] > 1) { q.pop(); } } } //return the first appearence once char in current stringstream char firstAppearingOnce(){ if (q.empty()) return ‘#‘; return q.front(); } };
以上是关于单调队列的主要内容,如果未能解决你的问题,请参考以下文章