题目描述
思路
解法一:辅助栈
-
本题难点在于括号内嵌套括号,需要从内向外生成与拼接字符串,这与栈的先入后出特性对应。
-
算法流程:
-
构建辅助栈 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)