题目描述(简单难度)

232. Implement Queue using Stacks - 图1

使用栈来实现队列。

思路分析

225 题 是使用队列来实现栈,其中介绍了两种解法,解法一通过一个临时队列来实现 poppeek。解法二只修改 push 。下边的话,我们依旧借助之前的思想来解决这个问题。

解法一

通过一个临时栈,每次 pop 的时候将原来的元素都保存到临时栈中,只剩下最后一个元素,这个元素是第一个加入栈中的,对于队列就是第一个应该弹出的。然后再把原来的元素还原到栈中即可。

peek 的话是同理。

  1. class MyQueue {
  2. Stack<Integer> stack;
  3. /** Initialize your data structure here. */
  4. public MyQueue() {
  5. stack = new Stack<>();
  6. }
  7. /** Push element x to the back of queue. */
  8. public void push(int x) {
  9. stack.push(x);
  10. }
  11. /** Removes the element from in front of queue and returns that element. */
  12. public int pop() {
  13. int size = stack.size();
  14. //保存到临时栈中
  15. Stack<Integer> temp = new Stack<>();
  16. while (size > 0) {
  17. temp.push(stack.pop());
  18. size--;
  19. }
  20. int remove = temp.pop();
  21. //还原
  22. size = temp.size();
  23. while (size > 0) {
  24. stack.push(temp.pop());
  25. size--;
  26. }
  27. return remove;
  28. }
  29. /** Get the front element. */
  30. public int peek() {
  31. int size = stack.size();
  32. Stack<Integer> temp = new Stack<>();
  33. while (size > 0) {
  34. temp.push(stack.pop());
  35. size--;
  36. }
  37. int top = temp.peek();
  38. size = temp.size();
  39. while (size > 0) {
  40. stack.push(temp.pop());
  41. size--;
  42. }
  43. return top;
  44. }
  45. /** Returns whether the queue is empty. */
  46. public boolean empty() {
  47. return stack.isEmpty();
  48. }
  49. }
  50. /**
  51. * Your MyQueue object will be instantiated and called as such:
  52. * MyQueue obj = new MyQueue();
  53. * obj.push(x);
  54. * int param_2 = obj.pop();
  55. * int param_3 = obj.peek();
  56. * boolean param_4 = obj.empty();
  57. */

解法二

我们可以像 225 题 一样,只修改 push 函数。我们只需要每次将新来的元素放到栈底,然后将其他元素还原。

  1. class MyQueue {
  2. Stack<Integer> stack;
  3. /** Initialize your data structure here. */
  4. public MyQueue() {
  5. stack = new Stack<>();
  6. }
  7. /** Push element x to the back of queue. */
  8. public void push(int x) {
  9. Stack<Integer> temp = new Stack<>();
  10. int size = stack.size();
  11. //把原来的保存起来
  12. while (size > 0) {
  13. temp.push(stack.pop());
  14. size--;
  15. }
  16. //当前元素压到栈底
  17. stack.push(x);
  18. size = temp.size();
  19. //将原来的还原回去
  20. while (size > 0) {
  21. stack.push(temp.pop());
  22. size--;
  23. }
  24. }
  25. /** Removes the element from in front of queue and returns that element. */
  26. public int pop() {
  27. return stack.pop();
  28. }
  29. /** Get the front element. */
  30. public int peek() {
  31. return stack.peek();
  32. }
  33. /** Returns whether the queue is empty. */
  34. public boolean empty() {
  35. return stack.isEmpty();
  36. }
  37. }
  38. /**
  39. * Your MyQueue object will be instantiated and called as such:
  40. * MyQueue obj = new MyQueue();
  41. * obj.push(x);
  42. * int param_2 = obj.pop();
  43. * int param_3 = obj.peek();
  44. * boolean param_4 = obj.empty();
  45. */

解法三

上边两种解法都是使用了临时栈,先弹出再还原,每个元素会遍历两次。

参考 这里-amortized-C%2B%2B-Java-Ruby) ,我们使用两个栈,一个栈输入,一个栈输出。当需要查看或者出队的时候,我们就将输入栈元素依次放入到输出栈中,此时的输出栈的输出顺序刚好和队列是相符的。

这样的话,每个元素只会遍历一次了。

可以看一下代码。

  1. class MyQueue {
  2. Stack<Integer> input = new Stack();
  3. Stack<Integer> output = new Stack();
  4. public void push(int x) {
  5. input.push(x);
  6. }
  7. public int pop() {
  8. peek();
  9. return output.pop();
  10. }
  11. public int peek() {
  12. if (output.empty())
  13. while (!input.empty())
  14. output.push(input.pop());
  15. return output.peek();
  16. }
  17. public boolean empty() {
  18. return input.empty() && output.empty();
  19. }
  20. }

解法一和解法二的话是完全按照 225 题 的思想,解法三的话,相对解法一和解法二相对要好一些。

windliang wechat

添加好友一起进步~

如果觉得有帮助的话,可以点击 这里 给一个 star 哦 ^^

如果想系统的学习数据结构和算法,强烈推荐一个我之前学过的课程,可以点击 这里 查看详情