目录
一、代码功能说明
二、原代码存在的问题(逐点分析)
1. 数字只支持个位数,多位数直接报错
2. 结果拼接逻辑完全错误
3. 字符栈设计不合理
4. 循环结束后,栈中剩余普通字母没有处理
5. 栈类型选择误区
三、修复思路(标准栈解法)
四、修复后的完整代码 + 详细注释
五、代码执行演示(举例)
六、原代码 vs 修复版总结
一、代码功能说明
题目:字符串解码 规则示例:
- 3[a] → aaa
- 2[bc] → bcbc
- 3[a2[c]] → accaccacc
原代码思路:想用双栈分别存数字、字符,遇到 ] 就取出括号内字符,按数字重复拼接。
二、原代码存在的问题(逐点分析)
1. 数字只支持个位数,多位数直接报错
例如 10[ab],数字 10 会被拆成 '1'、'0' 依次压栈,最后只弹出一个字符,解析错误。
Character opPop = opStack.pop(); // 只能取单个字符
Integer num = Integer.valueOf(opPop);
2. 结果拼接逻辑完全错误
- 每次遇到 ] 直接拼到全局 res,无法处理嵌套(如 3[a2[c]])。
- 括号内字符出栈反转后,直接追加到最终结果,内层解码内容不能被外层再次重复。
3. 字符栈设计不合理
把 [ 也压入字符栈,逻辑勉强能用,但配合全局 res 后嵌套场景彻底失效。
4. 循环结束后,栈中剩余普通字母没有处理
例如 2[a]bc,末尾 bc 会被留在栈中,最终结果丢失。
5. 栈类型选择误区
用 Deque<Character> 存数字很别扭,数字建议单独用数字栈(Integer),字符用字符串栈,更符合解题常规思路。
三、修复思路(标准栈解法)
标准解法使用两个栈:
流程:
- 弹出重复次数 k
- 弹出栈中保存的前缀字符串
- 当前字符串重复 k 次,拼接到前缀后,作为新的当前字符串
四、修复后的完整代码 + 详细注释
import java.util.ArrayDeque;
import java.util.Deque;
class Solution {
public String decodeString(String s) {
// 数字栈:存放每个 [ 对应的重复次数
Deque<Integer> numStack = new ArrayDeque<>();
// 字符串栈:存放 [ 之前已经拼接好的字符串
Deque<String> strStack = new ArrayDeque<>();
// 记录当前正在拼接的字符串
StringBuilder curStr = new StringBuilder();
// 记录当前解析到的数字(支持多位数)
int curNum = 0;
for (char c : s.toCharArray()) {
// 1. 处理数字(支持多位数)
if (Character.isDigit(c)) {
curNum = curNum * 10 + (c – '0');
}
// 2. 处理字母,直接拼接到当前字符串
else if (Character.isLetter(c)) {
curStr.append(c);
}
// 3. 遇到 [:压栈,重置临时变量
else if (c == '[') {
numStack.push(curNum);
strStack.push(curStr.toString());
curNum = 0; // 数字清零
curStr.setLength(0);// 当前字符串清空
}
// 4. 遇到 ]:开始重复拼接
else if (c == ']') {
// 取出重复次数
int k = numStack.pop();
// 取出 [ 前面的旧字符串
String preStr = strStack.pop();
// 临时保存当前要重复的内容
StringBuilder temp = new StringBuilder();
// 重复 k 次
for (int i = 0; i < k; i++) {
temp.append(curStr);
}
// 旧字符串 + 重复后的字符串 = 新的当前字符串
curStr = new StringBuilder(preStr + temp);
}
}
return curStr.toString();
}
}
五、代码执行演示(举例)
以 3[a2[c]] 为例: