题目描述
k[内容] 表示把「内容」重复 k 次,可能嵌套。求解码后的字符串。
思路解析
遇到数字就记重复次数;遇到 [ 就把「当前已拼的串」和「次数」压栈,然后清空重来;遇到 ] 就弹出,把当前串重复 N 次接到弹出的旧串后面。
读到 3,遇到 [:读到数字 3。遇到 [:把 3 压数字栈、当前串(空)压字符串栈,然后清空当前串,进入括号内部。
遇到 [ 的动作叫存档:把当前的「次数」和「已拼字符串」分别压进两个栈,然后清零,进入括号里从头拼。
读到 a,再读 2、[:括号里先读到 a(当前串变 "a")。又遇到 2[:把 2 和 "a" 压栈,再清空当前串。栈在加深,就像进入更里层。
读到 c,遇到 ]:读到 c(当前串 "c")。遇到 ]:弹出次数 2 和旧串 "a",当前串 = 旧串 + "c"重复2次 = "acc"。回到上一层。
遇到 ] 做三件事:弹出次数 k、弹出旧串 prev,然后 cur = prev + cur 重复 k 次。相当于合上这层括号,把结果交回外层。
再遇到 ]:又遇到 ]:弹出次数 3 和旧串(空),当前串 = "acc" 重复 3 次 = "accaccacc"。两个栈都空,解码完成。
每个 [ 让我们「存档、深入一层」,每个 ] 让我们「读档、把这层结果重复后接回去」。栈天生适合嵌套。
遇到嵌套结构(括号、目录、表达式),就用栈把「外层状态」存起来,处理完里层再恢复。基本计算器、简化路径都是它。
参考代码(Python)
1numStack, strStack, cur, num = [], [], class="cl-str">"", 0
2for ch in s:
3 if ch.isdigit(): num = num*10 + int(ch) # 多位数字
4 elif ch == class="cl-str">"[":
5 numStack.append(num); strStack.append(cur) # 存档
6 num, cur = 0, class="cl-str">""
7 elif ch == class="cl-str">"]":
8 k = numStack.pop(); prev = strStack.pop()
9 cur = prev + cur * k # 读档、重复、拼接
10 else: cur += ch # 普通字母
11return cur复杂度分析
- 时间复杂度:O(输出长度) —— 每个输出字符生成一次
- 空间复杂度:O(嵌套深度) —— 两个栈
套路模板
记住骨架:遇「进入」就把外层现场压栈、遇「退出」就弹栈合并、否则累积当前层。注意 num*10+ 处理多位数字(如 12[a])。基本计算器、简化路径都是同款。
1# 括号 / 表达式 / 目录等嵌套结构都套
2stack, cur, num = [], class="cl-str">"", 0
3for ch in s:
4 if ch.isdigit(): num = num*10 + int(ch) # 多位数字累加!
5 elif ch == class="cl-str">"[": stack.append((cur,num)); cur,num = class="cl-str">"",0 # 存档
6 elif ch == class="cl-str">"]": prev,k = stack.pop(); cur = prev + cur*k # 读档合并
7 else: cur += ch
8return cur易错点
- ❌ 数字只读一位 → ✅ num = num*10 + 当前数字(次数可能多位,如 12[a])
- ❌ ] 时拼成 cur*k + prev → ✅ prev + cur*k(旧串在前、重复的新串在后,顺序别反)
以上文字与上方动画完全同一思路:先看动画建立直觉 → 读文字巩固 → 关掉页面自己默写一遍代码,能写出来才算真的掌握。