给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为:
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]
死
思路:参考 LeetCode题解
利用栈的先进后出,来间接保存 【每一层所出现的子串】及 【k所对应的重复次数栈】
- 初始化两个栈:每一层的【字符串栈】和【k所对应的重复次数栈】
- 遍历题目给定的字符串s,并判断字符char是 “数字” or “左方括号” or “右方括号” or “字母”
- 数字 '0' ~ '9':因为每一层k所对应的重复次数 有可能是单倍或数十倍(比如重复1次或11次),所以需要遍历完当前层出现的完整重复次数(完整倍数):num = num*10 + n。例如:11ab,先遍历到第一个字符 '1' 得到 num = 0*10 + 1 = 1,然后继续遍历第二个字符 '1' 从而得到 num = 1*10 + 1 = 11 ... 这里的 11ab 也就表示 ab重复出现11次。
- 左方括号 [:将上一层的result和num分别入栈保存,并清空重置对应记录,避免干扰下一层统计
- 右方括号 ]:此时说明内层已经从左 '[' 至右 ']' 遍历完成了,那么可以借助栈中数据来组装内层数据了。
在strStack栈中保存的外层子串 + 内层子串*在numStack栈中保存的内层重复次数,result = topStr + strings.Repeat(result, topNum)。
这里要注意:内层子串的重复次数是由方括号外的外层数字来最终决定的。 - 字母 'a' ~ 'z':不断追加每层的result结果即可 ~
时间复杂度:
记解码后得出的字符串长度为 S除了遍历一次原字符串 s,我们还需要将解码后的字符串中的每个字符都入栈,并最终拼接进答案中,故渐进时间复杂度为 O(S+∣s∣),即 O(S)。
空间复杂度:
记解码后得出的字符串长度为 S,这里用栈维护 TOKEN,栈的总大小最终与 S 相同,故渐进空间复杂度为 O(S)。
// 参考:https://leetcode.cn/problems/decode-string/solutions/264879/zhan-de-ji-yi-nei-ceng-de-jie-ma-liao-bie-wang-lia/?languageTags=golang func decodeString(s string) string { // 初始化每一层的【字符串栈】和【k所对应的重复次数栈】 strStack, numStack := []string{}, []int{} result, num := "", 0 for _, char := range s { if char >= '0' && char <= '9' { // 获取每一层要重复的次数:例如 12[ab],那么就需要获取到12(1*10+2)这个完整的数字 n, _ := strconv.Atoi(string(char)) num = num*10 + n } else if char == '[' { // 将上一层的result和num分别入栈保存,并清空对应记录,避免干扰下一层统计 strStack = append(strStack, result) result = "" numStack = append(numStack, num) num = 0 } else if char == ']' { // 组装每一层字符串数据 topStr := strStack[len(strStack)-1] // get top value strStack = strStack[:len(strStack)-1] // pop topNum := numStack[len(numStack)-1] // get top value numStack = numStack[:len(numStack)-1] // pop // 外层子串 + 内层子串*内层子串重复次数 result = topStr + strings.Repeat(result, topNum) } else { // 不断追加每层的result结果:例如ab[...],那么就要拼接获取到这一层ab这个完整的字符串 result += string(char) } } return result }