来源
lintcode-用栈实现队列
描述
正如标题所述,你需要使用两个栈来实现队列的一些操作。
队列应支持push(element),pop() 和 top(),其中pop是弹出队列中的第一个(最前面的)元素。
pop和top方法都应该返回第一个元素的值。
样例
1
| 比如push(1), pop(), push(2), push(3), top(), pop(),你应该返回1,2和2
|
挑战
仅使用两个栈来实现它,不使用任何其他数据结构,push,pop 和 top的复杂度都应该是均摊O(1)的
解题思路
暴躁版本
这道题首先很容易想到暴躁版本.
首先有两个栈,主栈main和辅助栈helper.
- push()的时候直接向main中添加.
- pop()/top()的时候,将当前所有元素从main出栈,然后helper入栈.然后弹出栈顶元素.
- 将弹出后的所有元素从helper出栈,main入栈,恢复原来的次序,方便后续继续push.
举例:
1 2 3
| 1. push(1) -----> main=1,helper=empty 2. push(2) -----> main=2,1.helper=empty 3. pop(1) -----> main=empty,helper=1,2 -> main=empty,helper=2 -> main=2,helper=empty.
|
这种方式简单粗暴,但是在pop()/top()的过程中,要先将元素从main全部转移至helper,出栈后有全部转移回来.这样转来转去的好麻烦.
有没有机智点的方案?
机制版本
还是有两个栈.
push操作也一样.
但是pop操作呢?首先也全部将main的元素转移至helper.然后出栈,出栈之后保留helper的元素.
为什么可以保留呢?
因为此时helper中的元素就是队列的FIFO顺序,我们只要按照顺序出栈,就等于出队.
只要在此期间的push操作的元素,全部保存至main,且不向helper添加.
当helper为空时,将main中的元素全部转移过来.
这样操作就可以满足题目中的push()和pop()时间复杂度都为O(1)的要求了.
好了不BB.上代码!
实现代码
暴躁版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| import java.util.Stack;
public class MyQueue {
private Stack<Integer> main = new Stack<>(); private Stack<Integer> helper = new Stack<>();
public MyQueue() { }
public void push(int element) { main.push(element); }
public int pop() { while (!main.empty()) { helper.push(main.pop()); } int result = helper.pop(); while (!helper.empty()) { main.push(helper.pop()); } return result; }
public int top() { while (!main.empty()) { helper.push(main.pop()); } int result = helper.peek(); while (!helper.empty()) { main.push(helper.pop()); } return result; } }
|
机制版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| import java.util.Stack;
public class MyQueue {
private Stack<Integer> main = new Stack<>(); private Stack<Integer> helper = new Stack<>();
public MyQueue() { }
public void push(int element) { main.push(element); }
public int pop() { if (helper.empty()) { while (!main.empty()) { helper.push(main.pop()); } } return helper.pop(); }
public int top() { if (helper.empty()) { while (!main.empty()) { helper.push(main.pop()); } } return helper.peek(); } }
|
完。
ChangeLog
2019-01-02 完成
以上皆为个人所思所得,如有错误欢迎评论区指正。
欢迎转载,烦请署名并保留原文链接。
联系邮箱:huyanshi2580@gmail.com
更多学习笔记见个人博客——>呼延十