题目描述
思路解析动画文字版
记住这句,下面每一帧都在演它。
初始:in、out 都空。
push(1):新元素一律压 in 栈。in=[1],out=[]。
push(2):新元素一律压 in 栈。in=[1,2],out=[]。
out 空,先倒栈。看 in 怎么翻进 out。
倒栈:in 顶 2 弹出压入 out(顺序翻转)。in=[1],out=[2]。
倒栈:in 顶 1 弹出压入 out(顺序翻转)。in=[],out=[2,1]。
peek 返回 1:翻转后队首浮到 out 顶,只读不弹。out=[2,1]。
pop 返回 1:out 非空就直接弹顶,无需倒栈。out=[2],in=[]。
push(3):新元素一律压 in 栈。in=[3],out=[2]。
pop 返回 2:out 非空就直接弹顶,无需倒栈。out=[],in=[3]。
批量入队后,出队时一次倒栈把它们全翻过去。
push(4):新元素一律压 in 栈。in=[3,4],out=[]。
push(5):新元素一律压 in 栈。in=[3,4,5],out=[]。
倒栈:in 顶 5 弹出压入 out(顺序翻转)。in=[3,4],out=[5]。
倒栈:in 顶 4 弹出压入 out(顺序翻转)。in=[3],out=[5,4]。
倒栈:in 顶 3 弹出压入 out(顺序翻转)。in=[],out=[5,4,3]。
peek 返回 3:翻转后队首浮到 out 顶,只读不弹。out=[5,4,3]。
pop 返回 3:out 非空就直接弹顶,无需倒栈。out=[5,4],in=[]。
pop 返回 4:out 非空就直接弹顶,无需倒栈。out=[5],in=[]。
push(6):新元素一律压 in 栈。in=[6],out=[5]。
push(7):新元素一律压 in 栈。in=[6,7],out=[5]。
pop 返回 5:out 非空就直接弹顶,无需倒栈。out=[],in=[6,7]。
倒栈:in 顶 7 弹出压入 out(顺序翻转)。in=[6],out=[7]。
倒栈:in 顶 6 弹出压入 out(顺序翻转)。in=[],out=[7,6]。
pop 返回 6:out 非空就直接弹顶,无需倒栈。out=[7],in=[]。
pop 返回 7:out 非空就直接弹顶,无需倒栈。out=[],in=[]。
验证:先进先出顺序 1..7 全部正确。两栈清空。
边界先想清。
两个高频追问。
参考代码
class MyQueue: def __init__(self): self.inS, self.outS = [], [] def push(self, x): self.inS.append(x) # 入队压 in 栈 def _move(self): if not self.outS: # out 空才倒栈 while self.inS: self.outS.append(self.inS.pop()) def pop(self): self._move(); return self.outS.pop() def peek(self): self._move(); return self.outS[-1] def empty(self): return not self.inS and not self.outS复杂度
- 时间:均摊 O(1),每个元素一生只被倒一次(in→out)
- 空间:O(n),两个栈共存 n 个元素
易错点
面试追问把动画讲成自己的话
追问为什么均摊是 O(1)?
追问反过来用栈实现栈中栈/用队列实现栈呢?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
下一个更大元素 I
LeetCode 496 · 简单 · 沿着 栈套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题