394. 字符串解码

中等 含交互动画

学完这道你应该能: 说清它为什么用「栈」,而不是死记步骤; 合上页面,自己默写出核心代码; 用 30 秒把思路讲清楚。

AI 私教 · 就着本题动画讲
卡住了不用硬扛,按 8 步把这题真正走通。
从读题、试解、找法到手写代码,边问边打勾,适合第一次系统学算法的同学。

题目描述

k[内容] 表示把「内容」重复 k 次,可能嵌套。求解码后的字符串。

s = "3[a2[c]]"
输出 = "accaccacc"

思路解析

直觉是「找到 k[...] 替换成重复 k 次」,但括号可以无限嵌套(3[a2[c]]),你不知道哪个 ] 配哪个 [,从外往里根本对不齐。难点就是嵌套

转折:嵌套 = 进出层,而栈天生管进出。维护一个当前串 cur 和当前次数 num。遇 [ 就把「num 和已拼的 cur」存档进两个栈、清空重来;遇 ]读档:弹出次数 k 和旧串 prev,令 cur = prev + cur×k。从里往外,每层闭合时正好结算。

读 '3':从左往右扫。读到数字 3,记下重复次数 num=3。两个栈都还空着。

读 '[' · 存档:遇到 [:存档!把次数 3 和当前串(空)分别压进两个栈,再清空 num、cur,从括号里头重新开始拼。

读 'a':读到字母 a,不是括号也不是数字,直接接到当前串后面:cur = "a"。

读 '2':读到数字 2,记下 num=2。它要修饰的是后面那个括号里的内容。

读 '[' · 再存档(更深一层):又遇到 [:再次存档,把 2 和 "a" 压栈,清空当前层。两个栈都长高了——这就是「进入更里一层」。

读 'c':在最里层读到 c,接到当前串:cur = "c"。

读 ']' · 读档(合上里层):遇到 ]:读档!弹出次数 2 和旧串 "a",令 cur = 旧串 + 这层串重复 2 次 = "acc"。栈各弹掉一层,回到外层。

读 ']' · 再读档(合上外层):又遇到 ]:弹出次数 3 和旧串(空),cur = "acc" 重复 3 次 = "accaccacc"。两个栈都空了。

扫描结束:整个 s 扫完,栈空,cur = "accaccacc" 就是解码结果。每个 [ 存一次档、每个 ] 读一次档,嵌套就这么被栈理顺了。

遇到嵌套结构(括号、目录、表达式),就用栈把「外层状态」存起来,处理完里层再恢复。基本计算器、简化路径都是它。

参考代码(Python)

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])。基本计算器、简化路径都是同款。

Python
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(旧串在前、重复的新串在后,顺序别反)

以上文字与上方动画完全同一思路:先看动画建立直觉 → 读文字巩固 → 关掉页面自己默写一遍代码,能写出来才算真的掌握

下一题 →121. 买卖股票的最佳时机 ← 返回题库