队列的最大值

队列的最大值

题目描述

请定义一个队列并实现函数 maxValue() 得到队列里的最大值,要求函数maxValue()、pushBack(); 和 popFront() 的均摊时间复杂度都是O(1)。

若队列为空,popFront() 和 maxValue()需要返回 -1

思路

借助一个辅助队列来实时记录当前队列的最大值

可以分为以下的情况:

情况1:后入队的元素比前一个元素小,那么入队时的元素,在辅助队列中也同时记录,出队也跟随出队

image

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

image

image

image

解题思路已经在上图很直观的体现出了,结合代码与思路参考一下:

入队方法

每次入队的新元素先跟辅助队列的队首(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;
    }
}
posted @ 2021-08-24 13:44  先破防再敲  阅读(230)  评论(0)    收藏  举报