解决方案
使用两个栈
入队(push)
新元素总是压入 s1
的栈顶,同时我们会把 s1
中压入的第一个元素赋值给作为队首元素的 front
变量。
出队(pop)
根据栈 LIFO
的特性,s1
中第一个压入的元素在栈底。为了弹出 s1
的栈底元素,我们得把 s1
中所有的元素全部弹出,再把它们压入到另一个栈 s2
中,这个操作会让元素的入栈顺序反转过来。通过这样的方式,s1
中栈底元素就变成了s2
的栈顶元素,这样就可以直接从s2
将它弹出了。一旦s2
变空了,我们只需把 s1
中的元素再一次转移到 s2
就可以了。
判断空(empty)s1
和 s2
都存有队列的元素,所以只需要检查 s1
和 s2
是否都为空就可以了。
取队首元素(peek)
我们定义了 front
变量来保存队首元素,每次 入队 操作我们都会随之更新这个变量。当 s2 为空,front
变量就是对首元素,当 s2
非空,s2 的栈顶元素就是队首元素。
代码
class MyQueue {
Stack<Integer> s1 = new Stack<>();
Stack<Integer> s2 = new Stack<>();
int front;
/** Initialize your data structure here. */
public MyQueue() {
}
/** Push element x to the back of queue. */
public void push(int x) {
if(s1.empty())
front = x;
s1.push(x);
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
if(s2.empty()){
while(!s1.empty())
s2.push(s1.pop());
}
return s2.pop();
}
/** Get the front element. */
public int peek() {
if(!s2.empty())
return s2.peek();
return front;
}
/** Returns whether the queue is empty. */
public boolean empty() {
return s1.empty()&&s2.empty();
}
}
/**
* 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();
*/