604 字
3 分钟
字符串解码

题目描述#

给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。

你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。

此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。

测试用例保证输出的长度不会超过 105

解题思路#

  1. 双栈辅助解析
    • 数字栈:存储重复次数(处理多位数)
    • 字符串栈:存储外层字符串片段
  2. 遍历状态管理
    • 遇到数字:解析完整数字入栈
    • 遇到[:将当前字符串入栈,清空临时串
    • 遇到]:弹出数字和字符串,重复当前串并拼接到外层
    • 遇到字母:直接追加到当前串
  3. 多层嵌套处理
    • 内层括号展开后自动拼接外层片段
    • 栈结构天然支持嵌套层级

关键洞察#

  1. 栈匹配原理
    • [ 和 ] 成对出现,栈深度对应嵌套层级
    • 弹出时自动关联对应数字和字符串片段
  2. 数字多字节处理
    • 连续数字字符需拼接为整数(“12” → 12)
    • 避免将多位数拆分为单数字
  3. 临时字符串作用
    • 存储当前层级待重复的字符串
    • 遇到[时保存现场,遇到]时展开
  4. 结果拼接方向
    • 内层展开结果拼接在外层字符串后
    • 符合从左到右解码顺序

复杂度分析#

指标说明
时间复杂度O(S):S为解码后字符串长度(每个字符生成一次)
空间复杂度O(S):栈空间最坏O(n) + 结果字符串O(S)(n为输入长度)

代码实现#

/**
* @param {string} s
* @return {string}
*/
var decodeString = function (s) {
const numStack = [], strStack = [];
let currentNum = 0, currentStr = '';
for (const char of s) {
if (/\d/.test(char)) {
currentNum = currentNum * 10 + Number(char);
} else if (char === '[') {
numStack.push(currentNum);
strStack.push(currentStr);
currentNum = 0;
currentStr = '';
} else if (char === ']') {
const repeatTime = numStack.pop();
currentStr = strStack.pop() + currentStr.repeat(repeatTime);
} else {
currentStr += char;
}
}
return currentStr;
};

相似题目#

字符串解码
https://website-truelovings-projects.vercel.app/posts/algorithms/字符串解码/
作者
欢迎来到StarSky的网站!
发布于
2025-08-14
许可协议
CC BY-NC-SA 4.0