剑指 Offer 59 - II. 队列的最大值

剑指 Offer 59 - II. 队列的最大值

题目

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

若队列为空,pop_front 和 max_value 需要返回 -1

思路

这题也是用单调队列来解决,参考链接:https://leetcode-cn.com/problems/dui-lie-de-zui-da-zhi-lcof/solution/mian-shi-ti-59-ii-dui-lie-de-zui-da-zhi-by-leetcod/

本算法基于问题的一个重要性质:当一个元素进入队列的时候,它前面所有比它小的元素就不会再对答案产生影响。
上面的性质是非常关键的。举个例子,如果我们向队列中插入数字序列 1 1 1 1 2,那么在第一个数字 2 被插入后,数字 2 前面的所有数字 1 将不会对结果产生影响。因为按照队列的取出顺序,数字 2 只能在所有的数字 1 被取出之后才能被取出,因此如果数字 1 如果在队列中,那么数字 2 必然也在队列中,使得数字 1 对结果没有影响。

这样的话,如果当前队列中元素是1 1 1 2,那么此时我们要从队列中弹出1,那么根据队列先进先出的原则,1可以直接弹出,因为1不是最大值,不会对弹出后队列的最大值造成影响,所以直接弹出就行了。如果要是弹出2,因为队列最大值是2,那么就要在单调数组中把2删除

代码

class MaxQueue {

    ArrayDeque<Integer> A = new ArrayDeque<>(); //用于存储队列中的最大值,是个单调不增队列
    ArrayList<Integer> L =new ArrayList(); //用于存储队列中的数据
    int head = 0; //指示队列的头
    int size  =0; //指示队列的尾。
    //其实,这里存储队列中的数据,可以用一个ArrayDeque来实现,就不需要head这个头指针了
    
    //构造函数
    public MaxQueue() {
        A = new ArrayDeque<>();
        L =new ArrayList();
    }
    // 返回单调队列A中的第一个元素就行了
    public int max_value() {
        if(size==0){
            return -1;
        }
        return A.peekFirst();
    }
    // 队列中加元素
    public void push_back(int value) {
        L.add(value); //首先将数据放入数组L中,然后将size++
        size++;
        // 对单调队列A中的最后的元素进行判断,删除比value小的元素
        while(!A.isEmpty() && A.peekLast()<value){ 
            A.pollLast();
        }
        A.addLast(value); //将value加入
    }
    //队列中弹出元素
    public int pop_front() {
        if(size==0){
            return -1;
        }
        if(L.get(head)<max_value()){
            
        }else{
            A.pollFirst(); //因为弹出的是最大值,所以需要把单调队列A中的第一个元素删除
        }
        size--;
        return L.get(head++);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值