【LeetCode热题100道笔记】字符串解码

题目描述

给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。
你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。
测试用例保证输出的长度不会超过 105。

示例 1:
输入:s = “3[a]2[bc]”
输出:“aaabcbc”

示例 2:
输入:s = “3[a2[c]]”
输出:“accaccacc”

示例 3:
输入:s = “2[abc]3[cd]ef”
输出:“abcabccdcdcdef”

示例 4:
输入:s = “abc3[cd]xyz”
输出:“abccdcdcdxyz”

提示:

  • 1 <= s.length <= 30
  • s 由小写英文字母、数字和方括号 ‘[]’ 组成
  • s 保证是一个 有效 的输入。
  • s 中所有整数的取值范围为 [1, 300]

思考

利用栈的先进后出特性处理嵌套的括号结构:遇到右括号时,从栈中弹出最近的左括号及其之间的子串,同时提取前面的数字作为重复次数,将子串按次数重复后重新压入栈中。通过这种方式,从内层到外层逐步解析嵌套结构,最终拼接栈中剩余元素得到结果。

算法过程

  1. 初始化栈:用于存储字符、数字和括号
  2. 遍历字符串
    • 若遇到非右括号字符,直接入栈
    • 若遇到右括号]
      • 弹出栈顶字符,直到遇到左括号[,拼接这些字符得到待重复子串t
      • 弹出左括号[
      • 继续弹出栈顶字符,直到非数字,拼接得到重复次数的字符串numStr
      • numStr转换为数字repeatNum,并将子串t重复repeatNum
      • 将重复后的字符串重新压入栈中
  3. 结果处理:遍历结束后,将栈中所有元素拼接即为解码后的字符串

时空复杂度分析

  • 时间复杂度:O(N),其中N是解码后字符串的长度。虽然存在重复拼接操作,但每个字符最终只会被处理一次
  • 空间复杂度:O(N),栈的最大空间取决于解码后字符串的长度和嵌套深度

代码

/**
 * @param {string} s
 * @return {string}
 */
var decodeString = function(s) {
    const stack = [];
    const n = s.length;
    for (let c of s) {
        if (c === ']') {
            let t = '';
            while (stack[stack.length-1] !== '[') {
                t = stack.pop() + t;
            }
            stack.pop(); // [
            let numStr = '';
            while (!isNaN(stack[stack.length-1])) {
                numStr = stack.pop() + numStr;
            }
            const repeatNum  = Number(numStr);
            for (let i = 0; i < repeatNum; i++) {
                stack.push(t);
            }
        } else {
            stack.push(c);
        }

    }

    return stack.join('');
};
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值