题目:
尝试使用栈(stack)来实现队列(queue)。
思路:
我们可以用两个栈来实现一个队列:因为我们需要得到先入先出的结果,所以必定要通过一
个额外栈翻转一次数组。这个翻转过程既可以在插入时完成,也可以在取值时完成。
队列是一种 先进先出(first in - first out, FIFO)的数据结构,队列中的元素都从后端(rear)入队(push),从前端(front)出队(pop)。
实现队列最直观的方法是用链表,但在这篇文章里我会介绍另一个方法 - 使用栈。
栈是一种 后进先出(last in - first out, LIFO)的数据结构,栈中元素从栈顶(top)压入(push),也从栈顶弹出(pop)。
为了满足队列的 FIFO 的特性,我们需要用到两个栈,用它们其中一个来反转元素的入队顺序,用另一个来存储元素的最终顺序。
class MyQueue {
private Stack<Integer> stack1;
private Stack<Integer> stack2;
private int front;
/** Initialize your data structure here. */
public MyQueue() {
stack1 = new Stack<>();
stack2 = new Stack<>();
}
/** Push element x to the back of queue. */
public void push(int x) {//入队
if (stack1.isEmpty())
front = x;
stack1.push(x);
}
public int pop(){//出队
if(stack2.isEmpty()){
while(!stack1.isEmpty()){
stack2.push(stack1.pop());
}
}
return stack2.pop();
}
/** Get the front element. */
public int peek() {
//我们定义了 front 变量来保存队首元素,每次 入队 操作我们都会随之更新这个变量。当 s2 为空,front 变量就是队首元素,当 s2 非空,s2 的栈顶元素就是队首元素。
if(!stack2.isEmpty()){
return stack2.peek();
}
return front;
}
/** Returns whether the queue is empty. */
public boolean empty() {
//s1 和 s2 都存有队列的元素,所以只需要检查 s1 和 s2 是否都为空就可以了
return stack1.isEmpty()&&stack2.isEmpty();
}
}
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/