什么是单调队列?
单调队列就是元素单调递增或单调递减的队列。C++没有直接支持这种数据结构,一般可以用双端队列(deque)来实现。
怎么构造单调队列?
看leetcode第239题(239. 滑动窗口最大值 - 力扣(LeetCode)),单调队列需要维护数组的滑动窗口内可能是最大值的元素。
我们设想这样一个数组:{1,3,-1,-3,5},如果滑动窗口大小就是5,那单调队列怎么判断谁有可能成为最大值呢?可以注意到{1,3}和{-1,-3,5}两个子数组是分别递增的,也就是说这个完整数组的走向是一个双驼峰形的,有可能是最大值的数就在两个驼峰上,通往两个驼峰的过程中遍历的元素要全部弹出,由于后一个驼峰又比前一个驼峰高(5>3),3不再可能是最大值,因而5入队时又要把3弹出,即最终{5}就是单调队列需要维护的元素。
总之,如果单调队列内部从大到小排列,那么在push时如果push的元素大于队尾元素(back),那么就要弹出一直弹出队尾元素(这就是使用deque实现的好处,可以弹出队尾元素),直到要push的元素小于等于队尾元素或者单调队列已经为空。
单调队列和优先级队列有什么区别?
同样对于{1,3.-1,-3,5},它按照“越大的值优先级越高”的规则构造出来的优先级队列就应该是{5,3,1,-1,-3},而不仅仅是单调队列那样的{5}。显然,优先级队列做的工作是把元素按优先级排序,而单调队列是要找出可能是最大值(或最小值)的元素。
另外,按照“越大的值优先级越高”的规则构造出来的优先级队列就是大顶堆,同理可以构造出小顶堆。