力扣 - 232. 用栈实现队列.md
题目
思路1
- 即然是使用两个栈,那么一个栈就用来做辅助栈,一个栈用来存元素
- 我们将栈顶作为队头,将栈底作为队尾,所以如果要push数据的话,先将stack1栈的数据暂时存到stack2辅助栈中,然后将要插入的数据push进入stack1,最后再将stack2的暂存的数据填回到stack1中(注意,回填元素时顺序不能乱)
- pop时,就是将栈的元素最后一个pop出去,由于我们将队头做为栈顶,所以stack1的pop其实就是出队操作
- empty:要判断队列是否为空,直接判断stack1是否为空即可
- 由于栈是基于LinkedList实现的,peek时即查看的是栈顶的元素,所以直接peek就是查看队头的元素
代码
class MyQueue {
Deque<Integer> mainStack;
Deque<Integer> helpStack;
public MyQueue() {
mainStack = new LinkedList<>();
helpStack = new LinkedList<>();
}
public void push(int x) {
while (!mainStack.isEmpty()) {
helpStack.push(mainStack.pop());
}
mainStack.push(x);
while (!helpStack.isEmpty()) {
mainStack.push(helpStack.pop());
}
}
public int pop() {
return mainStack.pop();
}
public int peek() {
return mainStack.peek();
}
public boolean empty() {
return mainStack.isEmpty();
}
}
复杂度分析
- 时间复杂度:
- push: \(O(N)\)
- pop: \(O(1)\)
- peek: \(O(1)\)
- empty: \(O(1)\)
- 空间复杂度:\(O(N)\)
思路2
- 我们将一个栈用作进栈
inStack,另一个栈用作outStack - 因为是将
inStack的中的所有元素pop出来,push到outStack中去,则发生位置反转,所以outStack的栈顶元素就是我们队列的队头 - 出队元素的话只需要从
outStack中将栈顶元素pop即可 - 如果
outStack是 空的,就需要将inStack中的所有元素移动到outStack中去 - 注意:如果
outStack中如果不是空的,不能将inStack中的元素移过去,否则顺序被打乱
代码
class MyQueue {
Deque<Integer> inStack;
Deque<Integer> outStack;
public MyQueue() {
inStack = new LinkedList<Integer>();
outStack = new LinkedList<Integer>();
}
public void push(int x) {
// 因为inStack作用就是用于进栈,所以无需其他判断条件
inStack.push(x);
}
public int pop() {
// 如果outStack是空的,那么就需要将inStack中的元素移动到outStack中去,然后再pop
if (outStack.isEmpty()) {
move();
}
return outStack.pop();
}
public int peek() {
if (outStack.isEmpty()) {
move();
}
return outStack.peek();
}
// 只有两个栈都是空的,就说明队列是空的
public boolean empty() {
return inStack.isEmpty() && outStack.isEmpty();
}
// 将inStack中的元素移动到outStack中
public void move() {
while (!inStack.isEmpty()) {
outStack.push(inStack.pop());
}
}
}
复杂度分析
- 时间复杂度:
- push: \(O(1)\)
- pop: \(O(N)\)
- peek: \(O(N)\)
- empty: \(O(1)\)
- 空间复杂度:\(O(N)\)
我走得很慢,但我从不后退!

浙公网安备 33010602011771号