字符串解码问题(LeetCode 394题)是算法面试中的经典题型,主要考察对栈结构的理解和应用能力。题目要求将一个经过编码的字符串按照特定规则展开,例如将"3[a]2[bc]"解码为"aaabcbc"。
这类问题在实际开发中有着广泛的应用场景:
给定一个编码字符串的格式规则:
注意:题目中的medium难度评级意味着需要合理设计数据结构,但不需要特别复杂的数学推导。
最直观的解法可能是递归处理每个括号对,但这种方法存在明显缺陷:
栈结构特别适合处理具有"最近相关性"的问题,在本场景中表现为:
这种"后进先出"的特性与栈的操作模式完美契合。使用单栈可以同时保存两种信息:
以下是完整的算法步骤(Python实现):
python复制def decodeString(s: str) -> str:
stack = []
current_str = ""
current_num = 0
for char in s:
if char.isdigit():
current_num = current_num * 10 + int(char)
elif char == '[':
stack.append((current_str, current_num))
current_str = ""
current_num = 0
elif char == ']':
prev_str, num = stack.pop()
current_str = prev_str + current_str * num
else:
current_str += char
return current_str
数字处理:
current_num = current_num * 10 + int(char)处理多位数字入栈时机:
出栈处理:
| 输入案例 | 预期输出 | 处理要点 |
|---|---|---|
| "3[a]2[bc]" | "aaabcbc" | 基础测试 |
| "3[a2[c]]" | "accaccacc" | 嵌套测试 |
| "2[abc]3[cd]ef" | "abcabccdcdcdef" | 混合测试 |
| "10[a]" | "aaaaaaaaaa" | 多位数测试 |
| "1[a1[b1[c]]]" | "abc" | 深度嵌套 |
数字拼接顺序:
栈的存取顺序:
字符串拼接方向:
虽然单栈足够高效,但双栈方案(数字栈和字符串栈分离)有时更直观:
python复制def decodeString(s):
str_stack = []
num_stack = []
current = ""
num = 0
for char in s:
if char.isdigit():
num = num * 10 + int(char)
elif char == '[':
str_stack.append(current)
num_stack.append(num)
current = ""
num = 0
elif char == ']':
current = str_stack.pop() + current * num_stack.pop()
else:
current += char
return current
虽然不推荐,但递归方案可以帮助理解问题本质:
python复制def decodeString(s):
def helper(s, i):
res = ""
while i < len(s) and s[i] != ']':
if not s[i].isdigit():
res += s[i]
i += 1
else:
num = 0
while i < len(s) and s[i].isdigit():
num = num * 10 + int(s[i])
i += 1
i += 1 # skip '['
tmp, i = helper(s, i)
res += tmp * num
i += 1 # skip ']'
return res, i
return helper(s, 0)[0]
许多模板引擎(如Jinja2)的变量展开机制与此算法类似:
{{开始标记时保存上下文}}时进行值替换处理嵌套JSON时也需要类似的栈操作:
json复制{
"user": {
"name": "Alice",
"age": 25
}
}
解析器需要:
{时创建新对象并入栈}时弹出栈顶对象在语法分析阶段,编译器需要:
经过多次实践验证,我总结出以下经验:
可视化调试技巧:
code复制遇到3: current_num=3
遇到[: stack=[("",3)], current_str="", current_num=0
遇到a: current_str="a"
遇到2: current_num=2
遇到[: stack=[("",3), ("a",2)], current_str="", current_num=0
遇到c: current_str="c"
遇到]: prev_str="a", num=2 → current_str="a"+"c"*2="acc"
遇到]: prev_str="", num=3 → current_str=""+"acc"*3="accaccacc"
测试用例设计原则:
编码实现建议:
面试应答策略:
在实际开发中遇到类似字符串处理问题时,这种栈的应用模式可以扩展到许多场景。比如处理HTML标签嵌套、解析数学表达式等,核心思路都是利用栈保存上下文并在适当时机进行回溯处理。