目录
队列的最大值
描述
请定义一个队列并实现函数 max_value 得到队列里的最大值,要求函数max_value、push_back 和 pop_front 的均摊时间复杂度都是O(1)。
若队列为空,pop_front 和 max_value 需要返回 -1
示例 1
输入
["MaxQueue","push_back","push_back","max_value","pop_front","max_value"] [[],[1],[2],[],[],[]]
输出
[null,null,null,2,1,2]
示例 2
输入
["MaxQueue","pop_front","max_value"] [[],[],[]]
输出
[null,-1,-1]
限制
- 1 <= push_back, pop_front, max_value的总操作数 <= 10000
- 1 <= value <= 10^5
方法:单调双端队列
本题看着和剑指Offer(30)包含min函数的栈这题类似,但是还是有点细微的不同。
栈是先进后出,而队列是先进先出,所以当一个元素进入队列时,前面所有比它小的元素都不会对结果产生影响,换句话说:当较大的数在较小的数后面时,这个队列的最大值一直都是较大的数,因为要出队列也是较小数先出,较大数后出。
了解了这个性质我们就可以在入队时判断,将队列中前面所有小于当前值的数都出队。
class MaxQueue {
Queue<Integer> dataQueue;
Deque<Integer> maxQueue;
public MaxQueue() {
dataQueue=new LinkedList<>();
maxQueue=new LinkedList<>();
}
public int max_value() {
if (maxQueue.isEmpty()){
return -1;
}else{
return maxQueue.peekFirst();//获取队首元素
}
}
public void push_back(int value) {
while (!maxQueue.isEmpty() && maxQueue.peekLast()<value){
maxQueue.pollLast();//循环出队列中小于当前值的元素
}
maxQueue.offerLast(value);//将当前元素加到队尾
dataQueue.offer(value);//将当前元素加到数据队列中
}
public int pop_front() {
if (dataQueue.isEmpty()){
return -1;
}
int ans=dataQueue.poll();
if (ans==maxQueue.peekFirst()){
maxQueue.pollFirst();//如果出队列的元素和最大值队列中队首元素相同,则将最大值队列中的队首也出队
}
return ans;
}
}