image.png

解决方案

使用两个栈
入队(push)
新元素总是压入 s1 的栈顶,同时我们会把 s1 中压入的第一个元素赋值给作为队首元素的 front 变量。
出队(pop)
根据栈 LIFO 的特性,s1中第一个压入的元素在栈底。为了弹出 s1 的栈底元素,我们得把 s1中所有的元素全部弹出,再把它们压入到另一个栈 s2中,这个操作会让元素的入栈顺序反转过来。通过这样的方式,s1中栈底元素就变成了s2的栈顶元素,这样就可以直接从s2 将它弹出了。一旦s2变空了,我们只需把 s1 中的元素再一次转移到 s2 就可以了。
判断空(empty)
s1s2 都存有队列的元素,所以只需要检查 s1s2 是否都为空就可以了。
取队首元素(peek)
我们定义了 front 变量来保存队首元素,每次 入队 操作我们都会随之更新这个变量。当 s2 为空,front 变量就是对首元素,当 s2 非空,s2 的栈顶元素就是队首元素。

代码

  1. class MyQueue {
  2. Stack<Integer> s1 = new Stack<>();
  3. Stack<Integer> s2 = new Stack<>();
  4. int front;
  5. /** Initialize your data structure here. */
  6. public MyQueue() {
  7. }
  8. /** Push element x to the back of queue. */
  9. public void push(int x) {
  10. if(s1.empty())
  11. front = x;
  12. s1.push(x);
  13. }
  14. /** Removes the element from in front of queue and returns that element. */
  15. public int pop() {
  16. if(s2.empty()){
  17. while(!s1.empty())
  18. s2.push(s1.pop());
  19. }
  20. return s2.pop();
  21. }
  22. /** Get the front element. */
  23. public int peek() {
  24. if(!s2.empty())
  25. return s2.peek();
  26. return front;
  27. }
  28. /** Returns whether the queue is empty. */
  29. public boolean empty() {
  30. return s1.empty()&&s2.empty();
  31. }
  32. }
  33. /**
  34. * Your MyQueue object will be instantiated and called as such:
  35. * MyQueue obj = new MyQueue();
  36. * obj.push(x);
  37. * int param_2 = obj.pop();
  38. * int param_3 = obj.peek();
  39. * boolean param_4 = obj.empty();
  40. */