[路飞]_字符串解码

361 阅读1分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

leetcode-394 字符串解码

题目介绍

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

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

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

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

示例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]

思路解析

1646319149(1).png

看一下上图的例子,其实每一层的结构都是一样的,对于这种整体结构可以由部分结构来代替的题目,最好的解题方式就是使用递归,并且是只要看最小的一层结构就可以了。

那么以上图中的最小结构 6[ef] 来看一下怎么输出成字符串:

  1. 首先数字之后就是 [, 而 [ 到与其匹配的 ] 中的内容就是需要我们重复输出的内容,那么这里有两个值我们需要进行记录,一个是循环的次数 6,一个是循环的内容 ef
  2. 因为数字的范围是 [1, 300],所以当我们遇到第一个数字开始,需要遍历到 [ 为止,并且利用 num = num * 10 + +s[i] 方法记录完整的数字
  3. 遇到 [ 之后,直到遍历到 ] 为止,需要用字符串记录括号中的内容 ef
  4. 然后就可以在结果字符串后面拼接 numef 就可以了

接下来看一下如果是两层的 4[cd6[ef]] 怎么做:

  1. 首先还是记录循环次数 4
  2. 这里有两层括号,为了能够匹配到对应的括号,我们利用栈的思想,遇到 [+1,遇到 ]-1
  3. 记录括号中的内容 cd,然后遇到数字
  4. 这里就可以开始进入递归了,计算完 6[ef] 之后将结果返回到上一层,然后拼接在 cd 后面
  5. 当遇到 ] 且我们记录的值刚好为 0 时,说明当前的字符串是需要循环一开始记录的 4 次的
  6. 循环拼接,然后返回拼接后的字符串即可

更多层的结构同理

字符串解码.gif

解题代码

var decodeString = function(s) {
    let str = ''
    let i = 0
    while(s[i]) {
        if (s[i] < '0' || s[i] > '9') {
            // 如果不是数字,直接拼字符串
            str += s[i]
            i++
        } else {
            let num = 0
            // 如果是数字,需要遍历到 [,计算总数
            while (s[i] >= '0' && s[i] <= '9') {
                num = num * 10 + +s[i++]
            }
            i++
            let l = i, r = i, cnt = 1
            // 如果 cnt 不为 0,说明当前层的括号还没有封闭
            while(cnt) {
                r += 1
                if (s[r] === '[') cnt++
                if (s[r] === ']') cnt--
            }
            // 将 [] 中的内容进行递归,拼成字符串
            let temp = decodeString(s.substr(l, r - l))
            // 将 [] 中的内容循环 num 次拼接在当前的字符串之后
            while (num--) str += temp
            // r 此时指向 ],需要 +1 指向 ] 后面的元素
            i = r + 1
        }
    }
    return str
};