[LeetCode in Python] 394 (M) decode string 字符串解码

题目

https://leetcode-cn.com/problems/decode-string/

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

示例:

s = "3[a]2[bc]", 返回 "aaabcbc".
s = "3[a2[c]]", 返回 "accaccacc".
s = "2[abc]3[cd]ef", 返回 "abcabccdcdcdef".

解题思路(栈)

参考字符串解码(辅助栈法 / 递归法,清晰图解)

  • 从前向后扫描一次
  • 扫描中,遇到数字字符,使用n = n*10 + int(c)可更新数字
  • 遇到[时,用栈存储当前的乘数和字符串前缀,然后将这俩变量清零
  • 遇到]时,出栈乘数和此前的字符串前缀,据此更新当前字符串前缀
  • 这个解法需要注意:
    • 字符串前缀和乘数的清零时机
    • 入栈的内容,出栈后如何更新字符串前缀

代码(栈)

class Solution:
    def decodeString(self, s: str):
        stack = []

        n, res = 0, ''
        for c in s:
            if c.isdigit():
                # - update n
                n = n*10 + int(c)
            elif c.isalpha():
                # - update word
                res += c
            elif c == '[':
                # - use stack to keep current n and res
                stack.append([n, res])
                n, res = 0, ''
            elif c == ']':
                # - last n and res
                m, t = stack.pop()

                # - update res
                res = t + m*res
            else:
                pass
        
        return res

解题思路(递归)

参考字符串解码(辅助栈法 / 递归法,清晰图解)

  • 递归的思路是扫描到[就将递归处理此后的字符串,直到遇到]结束
  • 因为需要跳过处理过的子串,所以需要将结尾下标也作为返回值传出
  • 需要注意的是,获取到递归的返回值后,更新了字符串前缀,别忘了乘数重置为0

代码(递归)

class Solution:
    def decodeString(self, s: str):
        def dfs(i):
            res, n = '', 0
            while i < len(s):
                c = s[i]
                if c.isdigit():
                    n = n*10 + int(c)
                elif c.isalpha():
                    res += c
                elif c == '[':
                    r, i = dfs(i+1)
                    res += r * n
                    n = 0
                elif c == ']':
                    return res, i
                else:
                    pass

                i += 1
            return res, i

        return dfs(0)[0]

总结

其实DFS的递归,也是使用栈来存储临时变量的,二者没啥本质区别

posted @ 2020-04-16 03:34  ET民工[源自火星]  阅读(246)  评论(0编辑  收藏  举报