用两个栈实现队列

解题思路:

思路重点:一个栈倾倒到另一个栈时能够实现元素的倒序

  • 栈无法实现队列功能: 栈底元素(对应队首元素)无法直接删除,需要将上方所有元素出栈。

  • 双栈可实现列表倒序: 设有含三个元素的栈 A=[1,2,3] 和空栈 B=[]。若循环执行 A 元素出栈并添加入栈B ,直到栈 A 为空,则 A=[] , B=[3,2,1] ,即 栈 B 元素实现栈 A 元素倒序 。

  • 利用栈B删除队首元素: 倒序后,B执行出栈则相当于删除了 A 的栈底元素,即对应队首元素。

函数设计

题目只要求实现 加入队尾appendTail() 和 删除队首deleteHead() 两个函数的正常工作,因此我们可以设计栈 A 用于加入队尾操作,栈 B 用于将元素倒序,从而实现删除队首元素。

  • 加入队尾 appendTail()函数: 将数字 val 直接加入栈 A 即可。

  • 删除队首deleteHead()函数: 有以下三种情况。

    1. 当栈B不为空(无论A是否为空):B中仍有已完成倒序的元素,因此直接返回B的栈顶元素。

    2. 若B为空,A 为空:即两个栈都为空,无元素,返回-1 。

    3. 否则(即A不为空B为空),将栈A元素全部转移至栈B中,实现元素倒序,并返回栈B的栈顶元素。

代码展示

  • C++
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
class CQueue {
public:
stack<int> s1,s2;
CQueue() {

}

void appendTail(int value) {
s1.push(value);
}

int deleteHead() {
if(!s2.empty()){
int a = s2.top();
s2.pop();
return a;
}
if(s1.empty()){
return -1;
}
else{
while(!s1.empty()){
s2.push(s1.top());
s1.pop();
}
int a = s2.top();
s2.pop();
return a;
}
}
};
  • Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class CQueue {
LinkedList<Integer> A, B;
public CQueue() {
A = new LinkedList<Integer>();
B = new LinkedList<Integer>();

public void appendTail(int value) {
A.addLast(value);
}
public int deleteHead() {
if(!B.isEmpty()) return B.removeLast();
if(A.isEmpty()) return -1;
while(!A.isEmpty())
B.addLast(A.removeLast());
return B.removeLast();
}
}

用两个栈实现队列
https://eliteguo.github.io/2023/01/02/用两个栈实现队列/
作者
EliteGUO
发布于
2023年1月2日
许可协议