1. 问题描述:
给定一个用字符串表示的整数的嵌套列表,实现一个解析它的语法分析器。列表中的每个元素只可能是整数或整数嵌套列表
提示:你可以假定这些字符串都是格式良好的:
字符串非空
字符串不包含空格
字符串只包含数字0-9、[、-、,、]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/mini-parser
2. 思路分析:
分析题目可以知道嵌套的整数列表可以看成是一棵二叉树,只有一个元素的时候可以看成是一个叶子节点,为列表的时候可以看成是一棵子树,将字符串看成二叉树之后我们就可以使用递归来解决了,当前的字符串位置s[u]不是左括号的时候说明是数字的开始(注意u表示当前递归的时候字符串位置设置为全局变量这样在递归返回的时候u的值才是最新的),也即叶子节点,叶子节点是不用往下递归的,在while循环中找到当前数字加入到NestedInteger()对象中,当前的字符串位置s[u]为左括号的时候说明是一棵子树则我们需要递归下去,并且我们可以知道一个右括号说明是递归方法的终止符,所以我们需要在循环中(while)递归并且在遇到右括号的时候终止循环,这样当遇到右括号之前我们其实是调用了很多个递归方法来处理这个当前匹配的左右括号中的所有元素。可以结合例子"[[123], [789, [456]]]"理解。往下递归的时候返回到上一层的实际上是处理当前匹配的左右括号的所有元素(包括数字以及嵌套的列表)。
3. 代码如下:
class Solution:
# u为全局变量这样在递归return到上一层的时候u是最新的位置
u = 0
def dfs(self, s: str):
res = NestedInteger()
if s[self.u] == "[":
# 跳过左括号
self.u += 1
# 遇到一个右括号表示终止符号
while s[self.u] != "]":
res.add(self.dfs(s))
# 跳过右括号
self.u += 1
# 跳过逗号
if self.u < len(s) and s[self.u] == ",": self.u += 1
else:
k = self.u
while k < len(s) and s[k] != "," and s[k] != "]":
k += 1
res.setInteger(int(s[self.u: k]))
# 跳过逗号
if k < len(s) and s[k] == ",": k += 1
# 更新当前u的位置
self.u = k
return res
def deserialize(self, s: str) -> NestedInteger:
return self.dfs(s)