题目

https://leetcode.cn/problems/implement-stack-using-queues/description/
思路
两个队列
利用两个队列倒腾数据,保证一个队列始终为空,用来暂存除"栈顶"外的所有元素。
-
每次
push总是往非空队列里加(保证一个队列为空) -
每次
pop/top都把前n-1个元素倒腾到空队列,剩下的就是栈顶

一个队列
利用队列的循环特性,通过旋转操作让最后进来的元素跑到最前面。

code
一个易错的写法(使用两个队列)
java
class MyStack {
Deque<Integer> queue1 = new ArrayDeque<>();
Deque<Integer> queue2 = new ArrayDeque<>();
public MyStack() {
}
public void push(int x) {
//如果都为空,随意放入一个栈中
if(empty()){
queue1.push(x);
}else if(queue1.isEmpty()==true){//queue1为空就放入queue2
queue2.push(x);
}else{//queue2为空就放入queue1
queue1.push(x);
}
}
public int pop() {
//都为空
if(empty()){
return -1;
}else if(queue1.isEmpty()==false){//queue1不为空
//前面的都push到queue2中,queue2中的顺序也是对的
for(int i=0;i<queue1.size()-1;i++){
queue2.push(queue1.pop());
}
//最后一个pop
return queue1.pop();
}else{
//前面的都push到queue1中,queue1中的顺序也是对的
for(int i=0;i<queue2.size()-1;i++){
queue1.push(queue2.pop());
}
//最后一个pop
return queue2.pop();
}
}
public int top() {
int tmp=0;
//都为空
if(empty()){
return -1;
}else if(queue1.isEmpty()==false){
//前面的都push到queue2中,queue2中的顺序也是对的
for(int i=0;i<queue1.size();i++){
tmp=queue1.pop();
queue2.push(tmp);
}
//最后一个pop
return tmp;
}else{
//前面的都push到queue1中,queue1中的顺序也是对的
for(int i=0;i<queue2.size();i++){
tmp=queue2.pop();
queue1.push(tmp);
}
//最后一个pop
return tmp;
}
}
public boolean empty() {
return (queue1.isEmpty()==true && queue2.isEmpty()==true);
}
}
/**
* 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();
*/
pop /top方法中的致命错误
java
for(int i=0;i<queue1.size()-1;i++){
queue2.push(queue1.pop());
}
问题 :queue1.size() 在循环中会动态变化!每次 queue1.pop() 后,queue1.size() 会减少,导致循环次数错误。
正确做法:应该先保存 size。
java
int size = queue1.size();
for(int i = 0; i < size - 1; i++){
queue2.push(queue1.pop());
}
修正后的代码(使用两个队列)
java
class MyStack {
Deque<Integer> queue1 = new ArrayDeque<>();
Deque<Integer> queue2 = new ArrayDeque<>();
public MyStack() {
}
public void push(int x) {
// 简化:总是放入非空的队列,如果都空则放入 queue1
if(queue1.isEmpty()){
queue2.push(x);
} else {
queue1.push(x);
}
}
public int pop() {
if(empty()){
return -1;
}
if(!queue1.isEmpty()){
int size = queue1.size();
for(int i = 0; i < size - 1; i++){
queue2.push(queue1.pop());
}
return queue1.pop();
} else {
int size = queue2.size();
for(int i = 0; i < size - 1; i++){
queue1.push(queue2.pop());
}
return queue2.pop();
}
}
public int top() {
if(empty()){
return -1;
}
int tmp = 0;
if(!queue1.isEmpty()){
int size = queue1.size();
for(int i = 0; i < size; i++){
tmp = queue1.pop();
queue2.push(tmp);
}
return tmp;
} else {
int size = queue2.size();
for(int i = 0; i < size; i++){
tmp = queue2.pop();
queue1.push(tmp);
}
return tmp;
}
}
public boolean empty() {
return queue1.isEmpty() && queue2.isEmpty();
}
}
更简洁的实现(使用一个队列)
java
class MyStack {
Deque<Integer> queue = new ArrayDeque<>();
public void push(int x) {
queue.push(x);
int size = queue.size();
// 将前面的元素移到后面,实现栈的顺序
for(int i = 0; i < size - 1; i++){
queue.push(queue.pop());
}
}
public int pop() {
return queue.pop();
}
public int top() {
return queue.peek();
}
public boolean empty() {
return queue.isEmpty();
}
}