主要思想
在剑指offer面试题30:“包含min函数的栈”的解题思路中,可以想到这道题同样需要一个辅助队列,将当前队列的最大值存入辅助队列,但和栈又有所不同。
本题中:当一个元素value
入队的时候,它前面所有比它小的元素的出队不会对求最大值的结果产生影响,而它前面比它大的元素出队时,使得value
成为当前队列的最大值,直到有更大的数入队。
因此:设计辅助队列的入队、出队规则为:value入队时,将辅助队列中比value小的数依次出队。即“维持队列单调递减,保证每个元素的前面都没有比它小的元素”。出队操作是从队尾开始的,因此用到“双端队列”的数据结构。
数据结构:双端队列(Deque)
- 双端队列既可以当作队列来用,也可以当作栈来用。Java中实际上提供了java.util.Stack来实现栈结构,但官方文档目前已不推荐使用:
A more complete and consistent set of LIFO stack operations is provided by the Deque interface and its implementations, which should be used in preference to this class. For example: Deque<Integer> stack = new ArrayDeque<Integer>();
即推荐使用java.util.Deque双端队列来实现队列与栈的各种需求。
代码
class MaxQueue {
private Queue<Integer> queue;
private Deque<Integer> deque;
public MaxQueue() {
this.queue = new ArrayDeque<Integer>();
this.deque = new ArrayDeque<Integer>();
}
public int max_value() {
return this.queue.isEmpty()? -1 : this.deque.peekFirst();
}
public void push_back(int value) {
while(!this.deque.isEmpty() && value>this.deque.getLast())
this.deque.pollLast();
this.queue.add(value);
this.deque.addLast(value);
}
public int pop_front() {
if(this.deque.isEmpty())
return -1;
else
if(this.queue.peek().equals(this.deque.getFirst()))
{
this.deque.removeFirst();
return this.queue.poll();
}
else return this.queue.poll();
}
}