[栈和队列]用队列实现栈
一、题目描述
原文链接:225. 用队列实现栈
具体描述:
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
- void push(int x) 将元素 x 压入栈顶。
- int pop() 移除并返回栈顶元素。
- int top() 返回栈顶元素。
- boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
注意:
- 你只能使用队列的基本操作 —— 也就是 push to back、peek/pop from front、size 和 is empty 这些操作。
- 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。
示例:
输入:
[“MyStack”, “push”, “push”, “top”, “pop”, “empty”]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False
提示:
- 1 <= x <= 9
- 最多调用100 次 push、pop、top 和 empty
- 每次调用 pop 和 top 都保证栈不为空
进阶:你能否仅用一个队列来实现栈。
二、思路分析
栈和队列的基础知识!
两种方式:
第一种利用两个队列来实现:
暂且两个队列的名称分别是queue1(主队列)和queue2(辅助队列),针对push操作的时候,先添加到辅助队列queue2中,然后把queue1的元素都放倒queue2中,然后queue1等于queue2,queue2清空,这样的话先放到queue2中,说明每次添加的元素都是queue2的队头,这样不就是后进先出了嘛!然后pop,peek,empty都可以用queue1来操作就可以了!
第二种利用单个队列来实现:
这时候我们利用双端队列就可以了,在pop方法中,我们每次把队列的头部 放到队列的尾部就可以了,注意需要移动size - 1
次!最后一个元素就是栈顶!
三、AC代码
两个栈实现队列:
class MyStack { Queue<Integer> queue1; Queue<Integer> queue2;// 辅助队列 public MyStack() { queue1 = new LinkedList<>(); queue2 = new LinkedList<>(); } public void push(int x) { queue2.offer(x);// 把队尾放到第一个 while (!queue1.isEmpty()){ queue2.offer(queue1.poll());// 把之前的元素放到queue2中! } Queue<Integer> tmp = queue1; queue1 = queue2;// 把结果放到queue1中 queue2 = tmp;// 保持queue2是空元素,从而是得每次存储的元素都是队头! } public int pop() { return queue1.poll(); } public int top() { return queue1.peek(); } public boolean empty() { return queue1.isEmpty(); }}/ * Your MyStack object will be instantiated and called as such: * MyStack obj = new MyStack(); * obj.push(x); * int param_2 = obj.pop(); * int param_3 = obj.top(); * boolean param_4 = obj.empty(); */
利用双端队列实现栈:
class MyStack { Deque<Integer> deque; public MyStack() { deque = new ArrayDeque<>(); } public void push(int x) { deque.addLast(x); } public int pop() {int size = deque.size() - 1;// 保留最后一个元素,因为最后一个元素就是栈顶元素while (size-- > 0){ deque.addLast(deque.pollFirst());}int res = deque.peekFirst();deque.pollFirst();return res; } public int top() { return deque.peekLast(); } public boolean empty() { return deque.isEmpty(); }}/ * Your MyStack object will be instantiated and called as such: * MyStack obj = new MyStack(); * obj.push(x); * int param_2 = obj.pop(); * int param_3 = obj.top(); * boolean param_4 = obj.empty(); */
四、总结
- 单边队列和双端队列的用法!
感谢大家的阅读,我是Alson_Code,一个喜欢把简单问题复杂化,把复杂问题简单化的程序猿! ❤