面试题59 - II. 队列的最大值

问题

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

若队列为空,pop_front 和 max_value 需要返回 -1
在这里插入图片描述

例子

在这里插入图片描述

思路
本质是求滑动窗口最大值的问题。这个队列可以看成是一个滑动窗口,入队就是将窗口的右边界右移,出队就是将窗口的左边界右移。滑动窗口最大值:需要辅助双向队列【存放递减的值】

只用一个队列时,当队列头部元素出来时,就没办法知道接下来哪个是最大

  • 方法1
    $$

    $$

    队列存放元素
    辅助递减双向队列:队列头部是到目前为止最大的数
    如果入队列:入队列,则从后向前看递减队列,如果数<=元素,弹出,然后把元素放进递减队列
    如果出队列:如果元素==递减队列的头部,弹出队列,同时弹出递减队列

在这里插入图片描述

  • 方法2
    $$

    $$

代码

//方法1
class MaxQueue {
    Queue<Integer> q = new LinkedList<>();
    Deque<Integer> dq = new ArrayDeque<>();//递减队列
    public MaxQueue() {

    }
    
    public int max_value() {
        return q.size()==0?-1:dq.peekFirst();
    }
    
    public void push_back(int value) {
        q.offer(value);
        //value> ,不能有==,防止入队列的是:2,2,2
        while(dq.size()>0 && value>dq.peekLast())
            dq.pollLast();
        
        dq.offerLast(value);
    }
    
    public int pop_front() {//要从前面弹出
        if(q.size()==0) return -1;
        // int res = q.poll();
        //不能用while,只能去掉一个,如:入队列的是2,2,2,一下全弹出了,怎么行
        //空时,dq一定和q同时为空,但不空时,两者的size可能不同
       
        if(dq.peekFirst().equals(q.peek()))
            dq.pollFirst();
        
        return q.poll();
        
    }
}
//方法2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值