leetcode 394
题目:
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为: 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”.
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/decode-string
思路:
- 1.我的最开始思路:
类别解析字符串的算数表达式,用两个栈一个存数字,一个存字符串,左括号压栈,遇见右括号弹出字符栈直到左括号,并存为list ,reverse后 *数字栈弹栈生成对应单元。如果此时字符栈非空,即有嵌套的情况 则将生成好的list压入字符栈,否则将list 加入 result的列表(保存最后的结果)
最后检测字符串栈是否为空,不为空的话一直弹出 reverse 后加入result列表 并将列表转换为字符串返回。
- 2.出现的问题
1)对于大于十位数的数字 例如 20[leet]不能将20识别为一个整数
解决方法:
当读到数字的时候,用count记录该字符串一直读下去直到遇到左括号 将整个字符串转换为int 压入数字栈
- 3.我的通过代码
class Solution:
def decodeString(self, s: str) -> str:
s_n = []#数字栈
s_c = []#字符栈
result = []#最终结果
x=0
while x<len(s):#访问字符串
if s[x].isdigit():#遇到数字的话一直读直到遇到“["
count="".join(s[x])
while s[x+1]!="[":
count=count+s[x+1]
x+=1
s_n.append(int(count))
s_c.append("[")
x+=2
continue
if s[x].isalpha():
s_c.append(s[x])
x+=1
continue
if s[x] == "]":
num = s_n.pop()
list = []
ele = s_c.pop()
while ele != "[" :#弹字符串栈直到遇到[
list.append(ele)
ele = s_c.pop()
list.reverse()
list = num * list
if len(s_c) == 0:
result.extend(list)
else:#如果此时字符串栈非空 说明有嵌套的情况
s_c.extend(list)
x+=1
tem=[]#看最后还有没有单独的字符
while len(s_c) != 0:
tem.append(s_c.pop())
tem.reverse()
result.extend(tem)
str = "".join(result)
return str
复杂度太高 代码逻辑结构复杂
- 4.改进思路与代码
递归思想,实际就是算num*单元不断叠加即可
1)没必要多一个数字栈存数字,因为数字与单元是绑定的
对于多位数字
multi = multi * 10 + int(c)
2)遇到左括号,每个左括号意味着开始一个新的单元计算,将[该单元对应的倍数的数字,之前的结果]变成一个list压栈,数字与字符res置空记录新的单元元素。
3)遇到右括号,结算,弹出栈元素得到[该单元倍数,上一个结果],该单元的数字倍数*目前的res, 追加到上一个结果后赋值给res。
res = last_res + cur_multi * res
4)对于无倍数的字符res直接加
5)把每个单元内的字符直接用字符串记录,当作一个整体的res直接处理而不是一个一个字符压入就不用考虑reverse的问题。
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
代码知识点总结:
- 1.python字符串识别
对于str
for x in str:
x.isdigit():判断是否为数字 是则返回True
x.isalpha():判断是否为字母 是则返回True
- 2.list与str转换
str=“123”
list=list(str)
str=“www.sp"
list=str.split(".")
list=[1,2,3]
str="".join(list)
- 3.list 的基本操作
list.append()
list.extend(list)
list.reverse() #无返回值,原list变为逆序