题目
请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。
若队列为空,pop_front 和 max_value 需要返回 -1
解题思路
这题比较简单,首先我们需要一个队列, 可以先进先出的类,并且我们需要维护一个能弹出最大值的队列,所以这里需要两个队列, 一个照常放入数据和弹出第一个数据, 第二个队列我们使用之前做过的滑动窗口那题的单调队列,这里不适用最大堆的原因是无法顺序存放第二大的数据, 这里使用单调队列去做, 就可以按照递减返回第二大的数据了, 逻辑就是如果单调队列中的最后一个小于要存放的数据, 那么我们弹出单调队列最后的一个元素,可以一路弹出置空,然后放入需要放入的数据,因为我们是要弹出第一个数据的, 所以这样做事没有问题的,具体代码如下。
Java代码实现
import java.util.Deque;
import java.util.LinkedList;
public class MaxQueueTWO {
class MaxQueue {
Deque<Integer> dequeMax;
Deque<Integer> deque;
public MaxQueue() {
deque = new LinkedList();
dequeMax = new LinkedList<Integer>();
}
public int max_value() {
if(!dequeMax.isEmpty()){
return dequeMax.peek();
}else{
return -1;
}
}
public void push_back(int value) {
deque.add(value);
if(dequeMax.isEmpty()){
dequeMax.add(value);
}else{
int tmp = dequeMax.peekLast();
while(value > tmp && !dequeMax.isEmpty()){
dequeMax.removeLast();
if(!dequeMax.isEmpty()){
tmp = dequeMax.peekLast();
}
}
dequeMax.add(value);
}
}
public int pop_front() {
if(!deque.isEmpty()){
int tmp = deque.pollFirst();
if(!dequeMax.isEmpty()){
if(tmp == dequeMax.peek()){
dequeMax.pop();
}
}
return tmp;
}else{
return -1;
}
}
}
/**
* Your MaxQueue object will be instantiated and called as such:
* MaxQueue obj = new MaxQueue();
* int param_1 = obj.max_value();
* obj.push_back(value);
* int param_3 = obj.pop_front();
*/
}