欢迎光临
我们一直在努力

题目:字符串解码 解析

目录

一、代码功能说明

二、原代码存在的问题(逐点分析)

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),字符用字符串栈,更符合解题常规思路。


三、修复思路(标准栈解法)

标准解法使用两个栈:

  • 数字栈:保存 [ 前面的重复次数
  • 字符串栈:保存 [ 前面已拼接好的字符串
  • 用一个 StringBuilder 保存当前正在拼接的字符串
  • 流程:

  • 遇到数字:连续读取多位数字,拼接成完整数字,暂存。
  • 遇到 [:把当前字符串压入字符串栈,当前数字压入数字栈,清空当前字符串。
  • 遇到字母:直接追加到当前字符串。
  • 遇到 ]:
    • 弹出重复次数 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]] 为例:

  • 读到 3 → curNum = 3
  • 读到 [ → 压栈 num=3、str="",curNum=0, curStr=""
  • 读到 a → curStr = "a"
  • 读到 2 → curNum = 2
  • 读到 [ → 压栈 num=2、str="a",curNum=0, curStr=""
  • 读到 c → curStr = "c"
  • 读到 ] → 弹出 k=2、preStr="a" → curStr = "a" + "cc" = "acc"
  • 读到 ] → 弹出 k=3、preStr="" → curStr = "" + "accaccacc"
  • 遍历结束,返回 accaccacc

  • 六、原代码 vs 修复版总结

  • 原代码:字符栈 + 数字字符栈,不支持多位数、不支持嵌套、丢失末尾字符,逻辑架构错误。
  • 修复版:数字栈 + 字符串栈,标准栈解法,完美支持多位数、多层嵌套、末尾普通字符。
  • 时间复杂度:\\(O(n)\\),n 为解码后字符串长度,每个字符只处理有限次。
  • 赞(0)
    未经允许不得转载:171主机测评 » 题目:字符串解码 解析
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址