队列的最大值
队列的最大值
题目描述
请定义一个队列并实现函数 maxValue() 得到队列里的最大值,要求函数maxValue()、pushBack(); 和 popFront() 的均摊时间复杂度都是O(1)。
若队列为空,popFront() 和 maxValue()需要返回 -1
思路
借助一个辅助队列来实时记录当前队列的最大值
可以分为以下的情况:
情况1:后入队的元素比前一个元素小,那么入队时的元素,在辅助队列中也同时记录,出队也跟随出队

情况2:后入队的元素比前一个元素大(相等也可以),由图可知,如果有更大的入队会把前面比他小的全部都拿出来,而出队的时候同理,如果主队列中的元素不等于辅助队列的队首,辅助队列就不会出队,而此时队列的最大值就记录在了辅助队列的队首



解题思路已经在上图很直观的体现出了,结合代码与思路参考一下:
入队方法
每次入队的新元素先跟辅助队列的队首(peekFirst方法)进行比较,如果新元素的值比队首大,那么把辅助队列中比新元素小的元素全部都出队
如果比队首小,那么两个直接入队就可以了
出队方法
主队列先出队,如果辅助队列的队首与出队的元素的值相等,才进行辅助队列的出队操作(在代码中,有对与当前队列最大值相等的元素进队进行处理)
public class MaxQueue {
//主队列
Queue<Integer> queue;
//辅助队列,由于涉及到头尾维护,使用双端队列实现
Deque<Integer> deque;
//使用构造器来进行队列的初始化
public MaxQueue() {
queue = new LinkedList<>();
deque = new LinkedList<>();
}
//获取最大值的方法
public int maxValue() {
if (deque.isEmpty()) {
return -1;
}
return deque.peekFirst();
}
//入队方法
public void pushBack(int value) {
while (!deque.isEmpty() && deque.peekLast() < value) {
deque.pollLast();
}
deque.offerLast(value);
queue.offer(value);
}
//出队方法
public int popFront() {
if (queue.isEmpty()) {
return -1;
}
int ans = queue.poll();
if (ans == deque.peekFirst()) {
deque.pollFirst();
}
return ans;
}
}

浙公网安备 33010602011771号