第3章|栈与队列
Unit 12 · 多层上下文栈综合实验
进入更深一层之前,
先把外层世界完整保存下来。
嵌套字符串不能只靠一个重复次数和一段局部文本完成。每遇到左括号,都要把“进入内层之前的字符串”和“本层重复次数”压入上下文栈;右括号到达时,再弹出最近一层并完成合并。
题目要求
给定编码字符串 s,返回解码后的字符串。规则 k[encoded_string] 表示方括号中的字符串恰好重复 k 次;输入始终合法,数字只用于表示重复次数。
输入、输出与复杂度
- 输入:由小写字母、数字和方括号组成的合法编码字符串;
- 输出:完全展开后的字符串;
- 主方法:单次扫描输入,额外状态与嵌套深度相关;生成字符的工作至少与输出长度相关。
示例
输出:"aaabcbc"
输出:"accaccacc"
输出:"abcabccdcdcdef"
数据约束
1 ≤ s.length ≤ 30- 所有重复次数均在
[1, 300]; - 输入保证有效,解码后长度不超过
10⁵。
进入一个新括号层前保存的快照:外层已完成字符串与当前重复次数。
当前最内层尚未闭合区间已经解码的内容;它只属于当前递归深度。
多位次数必须按 current_number × 10 + digit 累积,不能把“12”理解成 1 与 2 两次重复。
栈中从底到顶依次保存每个未闭合外层的前缀与重复次数,栈顶对应最近进入的一层。
Unit 11 → Unit 12|容器保存的不是“数据”,而是尚未完成的决策状态
候选留在堆中,是因为它仍有资格进入 Top-K;容量超限时,最弱候选离开。
外层状态留在栈中,是因为内层尚未闭合;匹配的右括号到达时,最近上下文恢复。
当前最内层状态 数字先累积,字母追加到局部字符串
Context Frame Stack 栈顶 = 最近未闭合外层
关闭内层后既要知道重复多少次,也要把结果接回进入内层前已经形成的外层前缀。
最后进入的括号层最先闭合,恢复顺序天然满足后进先出。
读到第一个“[”时,哪一个栈帧应被保存?
提示 1|数字 多位重复次数不能覆盖旧值,应使用十进制累积:old × 10 + digit。 提示 2|左括号 进入新层会清空两个局部变量,因此先把 previous_string 与 repeat 作为同一个栈帧保存。 提示 3|右括号 先弹出最近栈帧,再按 previous_string + current_string × repeat 恢复父上下文。 查看提示不会解锁迁移;正确补全代码或走完整轨迹后才会解锁。
迁移题:LeetCode #1190「反转每对括号间的子串」
保留“进入内层前保存父上下文、关闭时恢复最近父层”的栈帧模型,但删除重复次数字段,并把右括号的合并规则改为:previous_string + reverse(current_string)。
LeetCode 1190 · 反转每对括号间的子串
题目要求
给定只包含小写英文字母和括号的字符串 s,按照从内到外的顺序,逐层反转每对匹配括号中的字符串,返回不含任何括号的最终结果。
约束
1 ≤ len(s) ≤ 2000- 只包含小写字母与圆括号
- 所有括号保证成对匹配
官方示例
输出契约:结果中不得保留括号;每一层关闭时都只处理当前最内层。
读题检查 1|函数返回什么?
读题检查 2|为什么 love 先反转?
#394 · 字符串解码
(previous_string, repeat)previous + current * repeat#1190 · 括号内反转
previous_stringprevious + current[::-1]迁移判断|什么被保留,什么被替换?
槽位 1|栈中保存什么?
进入括号后,哪份父层状态会被覆盖?
槽位 2|左括号后如何进入新层?
父前缀保存后,当前层应从何处开始?
槽位 3|右括号如何合并?
先处理当前最内层,再恢复父前缀。
槽位 4|普通字母如何处理?
字母属于当前最内层,暂不触发恢复。
class Solution:
def reverseParentheses(self, s: str) -> str:
stack = []
current_string = ""
for char in s:
if char == "(":
stack.append(current_string)
current_string = ""
elif char == ")":
current_string = stack.pop() + current_string[::-1]
else:
current_string += char
return current_string
"iloveu"Unit 12 Skill:把嵌套结构解析为上下文栈
看到括号嵌套、局部构造与关闭后恢复外层时,先问:进入内层前哪些变量会被覆盖?把这些变量组成栈帧;遇到关闭符号时弹出最近栈帧,并用题目规定的合并规则恢复父上下文。