单调队列
单调队列顾名思义,就是保持一定单调性的队列,他可以访问队头和队尾的元素,只能从队尾添加元素
假设队列的单调性为从队尾到队首单调递增,要保持队列的单调性,在向队尾添加元素时,需要比较队尾元素和要添加的元素(假设为n)的大小关系:
- 如果队尾元素大于n,那么将n添加到队尾
- 如果队尾元素小于n,那么将队尾元素弹出,比较n和新的队尾元素的大小关系,循环直至队列为空或者n小于队尾元素为止,将n添加到队尾
那么,这样维护后的队列就是一个单调(递增)队列。
举个例子,将1, 2, 45, 33, 66, 22, 9,逐个添加到单调队列中,看一下最后的队列是什么样子:
可以见到,最后得到的队列从队尾到队头依次为9,22,66,满足单调递增
用C++来实现一个基于deque的单调队列,代码如下:
class MyQueue{public:MyQueue() = default;//向队尾添加元素void push_back(int x){// 要保持队列的单调性,需要判断队尾元素的大小// 如果队尾元素小于要添加的元素,将队尾元素弹出,循环直到队列为空或者队尾元素大于要添加的元素为止while (!dq.empty() && dq.back() < x) {dq.pop_back();}dq.push_back(x);}// 弹出队头元素void pop_front(){dq.pop_front();}// 访问队头元素int front(){return dq.front();}// 访问队尾元素int back(){return dq.back();}bool empty(){return dq.empty();}public:deque<int> dq;};void test01(){vector<int> v{1, 2, 45, 33, 66, 22, 9};MyQueue mq;for (auto n : v){mq.push_back(n);}while (!mq.empty()){cout << mq.front() << endl;mq.pop_front();}}int main(){test01(); //输出结果为 66,22,9return 0;}
