单调队列

Posted jiguang321

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单调队列相关的知识,希望对你有一定的参考价值。

技术图片

 

 题目来自leetcode 239题滑动窗口最大值

如果使用暴力做法的话,每一次的窗口中都遍历找最大,这样的算法时间复杂度是O(n2),显然不符合要求!

这题应该使用单调队列来解决,时间复杂度为O(n)。

单调队列就是队列中的数据要么是单调递增,要么是单调递减的。

这里我们借助STL中的双端队列可以很好的实现单调队列。

代码如下

 1 class Solution 
 2 public:
 3     vector<int> maxSlidingWindow(vector<int>& a, int k) 
 4         vector<int> ans;
 5         if (k == 0)
 6             return a;
 7         deque<int> deq;
 8         for (int i = 0; i < a.size(); i++)
 9         
10             while (!deq.empty() && deq.back() < a[i]) deq.pop_back();
11             if (!deq.empty() && i >= k && a[i - k] == deq.front()) deq.pop_front();
12             deq.push_back(a[i]);
13             if (i >= k - 1)
14                 ans.push_back(deq.front());
15         
16         return ans;
17     
18 ;

 

while (!deq.empty() && deq.back() < a[i]) deq.pop_back();
每一个元素在入队的时候都要从队尾开始判断队列中的元素是否小于自己,如果小于的话就将其踢出队列,保证队列的单调性。

if (!deq.empty() && i >= k && a[i - k] == deq.front()) deq.pop_front();
  i>=k保证在前k个数据不会触发if条件,前k个元素之后,窗口开始移动,窗口最左边的元素会被移出,这个时候被移除的元素可能是最大值也可能不是。这个时候我们就要判断 a[i - k] == deq.front(),因为如果被移除的元素是最大值的话,那么它一定在队首,此时我们将对手元素出队就好了,而如果被移除的元素不是之前窗口中的最大值的话,我们就不用管它,因为那个元素早就被移出了队列了。

 

以上是关于单调队列的主要内容,如果未能解决你的问题,请参考以下文章

单调队列 单调栈

优先队列和单调队列一样吗?

单调队列以及单调队列优化DP

数据结构——单调栈&单调队列(解决滑动窗口问题)

单调队列模板

单调队列单调栈