[设计] 225. 用队列实现栈(两个队列法、一个队列法)
225. 用队列实现栈
题目链接:https://leetcode-cn.com/problems/implement-stack-using-queues/
分类:
- 设计:用队列模拟栈的四个操作(push,pop,top,empty)
- 队列:只能使用队列的基本操作模拟栈、方法有:两个队列法、一个队列法。
思路1:两个队列
队列的特点是先进先出,栈的特点是先进后出,要用队列来模拟栈,可以使用两个队列queue1,queue2,其中queue1作为主队列,queue2作为备份队列:
- push:元素加入队列1
- pop:要弹出的是最后加入queue1的元素,该元素存在于queue1的队尾,所以将队列1前面的元素全部出队,按顺序备份到queue2中,剩下的最后一个元素弹出,就是模拟栈的栈顶元素。但得到栈顶后,还需要将queue2的所有元素移回queue1,确保每次都以queue1为主队列,减少代码的复杂度,避免处理“两个队列交替工作的情况”。
- top:先调用pop获取栈顶元素,经过pop操作栈顶元素被删除了,而剩余的元素从queue2又移回了queue1。因为top函数只是获取栈顶元素并没有将它删除,而且我们要维持“这个元素是最后加入队列”这一特性,以确保每次执行pop,top都能得到准确的目标元素,所以将获取到的栈顶元素重新加入到队列1的末尾。
- empty:判断两个队列是否都为空,如果都为空,返回true。
class MyStack {
Queue<Integer> queue1;
Queue<Integer> queue2;
/** Initialize your data structure here. */
public MyStack() {
queue1 = new LinkedList<>();
queue2 = new LinkedList<>();
}
/** Push element x onto stack. */
public void push(int x) {
queue1.offer(x);
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
while(queue1.size() > 1){
queue2.offer(queue1.poll());
}
int last = queue1.poll();
//再将queue2的元素全部转移到queue1上
while(!queue2.isEmpty()){
queue1.offer(queue2.poll());
}
return last;
}
/** Get the top element. */
public int top() {
int top = pop();
queue1.offer(top);
return top;
}
/** Returns whether the stack is empty. */
public boolean empty() {
return queue1.isEmpty() && queue2.isEmpty();
}
}
思路2:一个队列
将思路1使用的两个队列缩减为一个队列:
- push:队列的offer函数
- pop:先获取当前队列内的元素个数n,开始依次弹出队首元素,每弹出一个元素就重新加到队尾,同时计数器+1,当计数器==n-1时,此时的队首就是模拟栈的栈顶,将其弹出即可。
- top:调用pop,但将栈顶元素再加回队尾。
- empty:同思路1.
class MyStack {
Queue<Integer> queue;
/** Initialize your data structure here. */
public MyStack() {
queue = new LinkedList<>();
}
/** Push element x onto stack. */
public void push(int x) {
queue.offer(x);
}
/** Removes the element on top of the stack and returns that element. */
public int pop() {
int n = queue.size();
int count = 0;
while(count < n - 1){
int top = queue.poll();
queue.offer(top);//加回队尾
count++;
}
return queue.poll();
}
/** Get the top element. */
public int top() {
int top = pop();
queue.offer(top);
return top;
}
/** Returns whether the stack is empty. */
public boolean empty() {
return queue.isEmpty();
}
}