【栈&队列】LeetCode 394. 字符串编码【中等】

示例 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. 构建辅助栈stack,遍历字符串s中每个字符c;

  当c为数字时,将数字字符转化为数字multi,用于后续倍数计算;

  当c为字母时,在res尾部添加c;

  当c为“[”时,将当前 multi 和 res 入栈,并分别 置空 和 置0 :

    记录此“[”前的临时结果res至栈,用于发现对应“]”后的拼接操作;

    记录此“[”前的倍数multi至栈,用于发现对应“]”后,获取multi * [...]字符串;

    进入到新“[”后,res和multi重新记录。

  当c为“]”时,stack出栈,拼接字符串 res = last_res + cur_multi * res,其中:

    last_res是上个“[”到当前“[”的字符串,例如 "3[a2[c]]" 中的 a

      cur_multi是当前 [ 到 ] 内字符串的重复倍数,例如 "3[a2[c]]" 中的 2

2. 返回字符串res。

时间复杂度: O(N),一次遍历s

空间复杂度:O(N),辅助栈在极端情况下需要线性空间,例如 2[2[2[a]]]。

class Solution:
    def decodeString(self, s: str) -> str:
        stack, res, multi = [], "", 0
        for c in s:
            if c == '[':
                stack.append([multi, res])
                res, multi = "", 0
            elif c == ']':
                cur_multi, last_res = stack.pop()
                res = last_res + cur_multi * res
            elif '0' <= c <= '9':
                multi = multi * 10 + int(c)            
            else:
                res += c
        return res

示例演示一遍,就更加清晰了,梳理出三条线:分别对于字母,数字,左右边界括号的处理逻辑!

方法二:递归解法

总体思路与辅助栈法一致,不同点在于“[”和“]”分别作为递归的开始与终止条件:

  当 s[i] == ']' 时,返回当前括号内记录的res字符串与']' 的索引i(更新上层递归指针位置);

  当 s[i] == '[' 时,开启新一层递归,记录此[...]内字符串tmp和递归后的最新索引i,并执行res + multi * tmp拼接字符串。

  遍历完毕后返回res。

时间复杂度:O(N),递归会更新索引,因此实际上还是一次遍历s。

空间复杂度:O(N),极端情况下递归深度将会达到线性级别。

class Solution:
    def decodeString(self, s: str) -> str:
        def dfs(s, i):
            res, multi = "", 0
            while i < len(s):
                if '0' <= s[i] <= '9':
                    multi = multi * 10 + int(s[i])
                elif s[i] == '[':
                    i, tmp = dfs(s, i + 1)
                    res += multi * tmp
                    multi = 0
                elif s[i] == ']':
                    return i, res
                else:
                    res += s[i]
                i += 1
            return res
        return dfs(s,0)

 

 

 

posted @ 2022-05-05 11:07  Ariel_一只猫的旅行  阅读(39)  评论(0编辑  收藏  举报