问题
请定义一个队列并实现函数 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