leetcode394 字符串解码

这篇博客讨论了解码编码字符串的算法,通过遍历输入字符串,利用栈的特性处理括号嵌套情况。当遇到数字时累计计数,遇到普通字符时加入临时结果,遇到'['时将当前计数和临时结果压栈,遇到']'时计算当前子串并更新结果。递归解法也可实现相同功能,空间复杂度为O(n)。
摘要由CSDN通过智能技术生成

给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: 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”

题由于保证了输入一定是有效的,因此我们可以不必考虑括号失配的情形。
由于存在括号嵌套的情况,因此我们不能简单的从左到右匹配输出,而是存在内层括号时,我们应该先算出内层括号中的字符串解码然后再由外层计算,这显然很符合栈 “先进后出”的特性。
对输入字符串s进行遍历,有如下情形:
1 当前字符为数字,那么我们将其累加起来,用做其后【…】字符串出现的次数
2 当前字符为普通字符,我们用一个临时结果集先将其连接
3 当前字符为 “【”,显然此时我们要进入括号内层了,所以进内层前,我们将之前的倍数和之前的 “临时结果集” 先放入栈中,根据栈的特性,我们会先算完内层才会计算外层。然后重置 “临时结果集”为“”, 倍数为0, 因为相当于进入了一个新的子状态。
4 当前字符为 “】”,此时,表示当前某一内层【…】已匹配完,我们向上弹出栈顶(前缀和倍数),将倍数 乘以【…】括号内的内容并加上前缀即可,作为当前的 “临时结果集”,由于进入【 的时候倍数已经置零了,而括号内不允许有数字,因此这个时候出括号的时候倍数还是0,不用管它。
时间复杂度是O(n)
空间复杂度是栈的大小O(n)

class Solution:
    def decodeString(self, s: str) -> str:
        num = 0
        cur = ''
        stack = []
        for elem in s:
            if elem in '0123456789':
                num = 10*num + int(elem)
            elif elem not in '0123456789[]':
                cur += elem 
            elif elem == '[':
                stack.append((num, cur))
                num = 0 
                cur = ''
            elif elem == ']':
                tempnum, temppre = stack.pop()
                cur = temppre + cur*tempnum 
                
        return cur 

可以看到,栈也可以用递归来代替,递归函数的内容为:
1 我们设置一个i指针,初始指向第一个字符, 然后开始往后遍历。注意递归函数需要将当前字符串置为’’ , 倍数置为0
2 当出现 “【”时,开启下一层递归, 递归返回的是【】里面的内容,和】的位置i,也就是这个时候指针直接跑到】的位置上去了。然后将这个内容呈上倍数并加上前缀得到当前的字符串。将倍数置为0
3 出现 “】”时,向上返回一层,返回当前字符串(也就是这层递归函数处理的【】里面的内容) 和 指针位置( 】的位置 )
空间复杂度O(n)为递归深度

class Solution:
    def decodeString(self, s: str) -> str:
        return self.decodeStringSub(s, 0)[0]

    def decodeStringSub(self, s, i):
        num = 0
        cur = ''
        while i < len(s):
            elem = s[i]
            if elem in '0123456789':
                num = 10*num + int(elem)
            elif elem not in '0123456789[]':
                cur += elem 
            elif elem == '[':
                tempcur, i = self.decodeStringSub(s, i+1)
                cur = cur + tempcur*num
                num = 0 
            elif elem == ']':
                return cur, i
            i += 1 
                
        return cur, i 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值