递归_or_栈_medium_394_字符串解码

题目描述

在这里插入图片描述

思路

解法一:辅助栈

  • 本题难点在于括号内嵌套括号,需要从内向外生成与拼接字符串,这与栈的先入后出特性对应。

  • 算法流程:

    • 构建辅助栈 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。

    • 返回字符串 res。

  • 复杂度分析:

    • 时间复杂度 O(N)O(N),一次遍历 s;
    • 空间复杂度 O(N)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
  • 暴力栈
class Solution:
    def decodeString(self, s: str) -> str:
        stack = []
        for index, c in enumerate(list(s)):
            if c == ']':
                res = []
                while stack and stack[-1] != '[':  # []的 ascii码 在 A-Z 和 a-z之间
                    res.append(stack.pop())
                if stack and stack[-1] == '[':
                    stack.pop()
                time = []
                while stack and '0' <= stack[-1] <= '9':
                    time.append(stack.pop())
                time = int(''.join(reversed(time)))
                res = list(reversed(res))
                res *= time
                stack += res
            else:
                stack.append(c)
        return ''.join(stack)

解法二:递归

在这里插入图片描述

def decodeString(self, s: str) -> str:
    def dfs(i):
        res, multi = "", 0
        #这里不能用for i in range(len(s)),因为递归调用时,新的循环不从0开始从i开始
        while i < len(s):
            #遇到数字
            if '0' <= s[i] <= '9':
                multi = multi * 10 + int(s[i])#考虑数字是2位以上的情况
            #遇到'['开始将后续的string递归
            elif s[i] == '[':
                i, tmp = dfs(i + 1)
                #注意,返回i的含义是更新上层递归指针位置,因为内层递归已经吃掉一串str,若不跟新i,外层仍然从i+1开始,则会重复处理内层处理过的一串str。
                res += multi * tmp
                multi = 0
            #遇到']'到达递归边界,结束递归,返回新i和处理好的内层res
            elif s[i] == ']':
                return i, res
            #遇到其他,则当字母串处理
            else:
                res += s[i]
            i+=1
        #考虑结尾是...]abc的情况
        return res
    
    return dfs(0)

Reference

https://leetcode-cn.com/problems/decode-string/solution/decode-string-fu-zhu-zhan-fa-di-gui-fa-by-jyd/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值