题目描述
思路解析动画文字版
下面 15 步动画会按主解代码推进,而不是泛泛讲题型。
1. 准备:空栈,j=0:用一个真栈模拟:按 pushed=[1,2,3,4,5] 依次入栈,只要栈顶等于 popped[j] 就弹出。当前栈空,j=0,下一个要弹的目标是 popped[0]=4。
2. 入栈 1:读 pushed 第 0 位 1,入栈。栈=[1],栈顶 1 不等于目标 popped[0]=4,不弹,继续读下一个。
3. 入栈 2:读 pushed 第 1 位 2,入栈。栈=[1,2],栈顶 2 不等于目标 4,不弹。
4. 入栈 3:读 pushed 第 2 位 3,入栈。栈=[1,2,3],栈顶 3 不等于目标 4,不弹。
5. 入栈 4:读 pushed 第 3 位 4,入栈。栈=[1,2,3,4],栈顶 4 等于目标 popped[0]=4,进入 while 弹出。
6. 弹出 4,j→1:弹出 4,j 变为 1,新目标是 popped[1]=5。此时栈顶 3 不等于 5,while 停止,回到入栈循环。
7. 入栈 5:读 pushed 第 4 位 5,入栈。栈=[1,2,3,5],栈顶 5 等于目标 popped[1]=5,进入 while 弹出。
8. 弹出 5,j→2:弹出 5,j 变为 2,新目标是 popped[2]=3。栈顶 3 等于 3,while 继续弹。
9. 弹出 3,j→3:弹出 3,j 变为 3,新目标是 popped[3]=2。栈顶 2 等于 2,while 继续弹。
10. 弹出 2,j→4:弹出 2,j 变为 4,新目标是 popped[4]=1。栈顶 1 等于 1,while 继续弹。
11. 弹出 1,j→5:弹出 1,j 变为 5,popped 已全部匹配。栈空,while 因栈空而停止。
12. 入栈循环结束:pushed 5 个数已全部读完,循环结束。栈为空,j=5,说明每个元素都按 popped 顺序成功弹出。
13. 判定:j == len(popped):最后比较 j 与 len(popped):j=5 等于 5,说明 popped 整个序列都被合法弹出,返回 true。
14. 反例对照:popped=[4,3,5,1,2]:若 popped 改成 [4,3,5,1,2]:弹完 4 后目标是 3,栈顶恰好是 3 也能弹;但接着目标 5 时,5 尚未入栈、栈顶变 2,最终 j 卡在 5 之前,循环结束 j 不等于 len(popped),返回 false。这说明栈只能从顶弹。
15. 性质:模拟即判定:关键性质:每个元素只能在它成为栈顶时弹出。所以遇到栈顶等于当前目标就立刻弹是唯一选择,不会漏掉合法弹序。整体每个数入栈一次、出栈一次,时间 O(n)。
记住这题的代码骨架:题意约束先落到状态变量,再用循环或递归维护它。
参考代码
class Solution: def validateStackSequences(self, pushed, popped): stack = [] j = 0 for x in pushed: stack.append(x) while stack and stack[-1] == popped[j]: stack.pop() j += 1 return j == len(popped)复杂度
- 时间复杂度:O(n),每个元素入栈出栈一次
- 空间复杂度:O(n),模拟栈
易错点
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
最长有效括号
LeetCode 32 · 困难 · 沿着 栈套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题