[数据结构学习]单调队列

单调队列,即内部元素相对于比较器有序的队列,可以方便的查询序列中某个连续区间内的最大/最小值

也能在状态转移时优化决策以降低时间复杂度。(嗯,这句是OI-Wiki上说的,作为蒟蒻qwq我并不知道如何优化dp)

比如我们想知道一个长为n的数字序列中每连续k个数中最小的那个数

如果暴力求解的话,遍历从1~n-k+1,复杂度O(n*k),而且需要将每个子序列中的值与其他值进行比较,是比较慢的=-=

对于这个问题就可以维护一个递减的单调队列,同时注意队列中的数字区间不要超过k

维护的方法:

每读入序列中的一个新的数,比较该数与队尾的数的关系

1.若该数大于队尾的数,入队。

2.若概述小于队尾的数,队尾的数出队,再次将该数与队尾的数进行比较。

入队后检查当前队首和队尾两个数所包含的数字区间是否超过k

如果超过则队首出队。

cin>>t;
while(!dq.empty() && dq.back() > t)
    dq.pop_back(), no.pop_back();
dq.push_back(t), no.push_back(i);
while(no.back() - no.front() >= k)
    dq.pop_front(), no.pop_front();

//这里是用deque做容器维护单调队列, no也是一个deque,维护在dq中数字的相应编号(下标)

 这样维护的队列的队首元素总是每k个元素中最小的

O(1)即可取出,而每个数最多出队一次入队一次,维护队列的时间复杂度仅为O(n)

原文地址:https://www.cnblogs.com/leafsblogowo/p/12687225.html