You need to construct a binary tree from a string consisting of parenthesis and integers.
The whole input represents a binary tree. It contains an integer followed by zero, one or two pairs of parenthesis. The integer represents the root's value and a pair of parenthesis contains a child binary tree with the same structure.
You always start to construct the left child node of the parent first if it exists.
Example 1:
Input: s = "4(2(3)(1))(6(5))" Output: [4,2,6,3,1,5]
Example 2:
Input: s = "4(2(3)(1))(6(5)(7))" Output: [4,2,6,3,1,5,7]
Example 3:
Input: s = "-4(2(3)(1))(6(5)(7))" Output: [-4,2,6,3,1,5,7]
Constraints:
0 <= s.length <= 3 * 104
s
consists of digits,'('
,')'
, and'-'
only.
给定一个字符串,要求构造一棵二叉树。字符串由小括号和数字组成。整个字符串表示一棵二叉树,结构是一个整数后面跟着0,1或2对小括号(一对由左右小括号组成),整数是根节点值,每队小括号里的内容分别表示一棵子树,其中总数左子树在前,右子树在后。小括号里的子字符串表示的子树具有相同的结构。
根据以上描述要从字符串取出一个完整的整数(即节点值)可以以括号字符为分隔符。任意一对括号(左右括号要匹配)里的子字符串表示一棵子树都具有相同结构,也就是说它们可以做相同的处理,因此很容易想到用递归来处理。以下来分析递归函数的实现
输入是一个具有以上所描述的结构的子字符串(为了避免子字符串的重复拷贝,可以用一个全局变量表示字符串的索引,每前进一个字符索引值就加1,这样递归函数的输入子字符串就是从当前索引值的位置开始的)。递归函数的第一步就是取出根节点值来创建根节点,从头挨个取出数字字符(边取字符时就可以边计算整数值),直到遇到左括号停止,计算完的整数值就是节点值(要是一直到结尾都没遇到左括号,表示没有子节点);第一个左括号表示左子树即开始做递归调用处理左子树,但在这之前全局索引值要加1即跳过左括号,这样保证进入递归函数时总是从数字字符开始的;左子树的递归调用处理完返回之后,如果全局索引指向的字符又是一个左括号,那表示还存在右子树,因此全局索引再加1,进入另一个递归调用处理右子树;右子树也处理完之后,即整棵树都构造完成,这时全局索引指向肯定是一个右括号因为左右括号总是成对匹配出现的, 因此在返回之前,全局索引还得加1使得右括号与进入递归调用函数之前的左括号要匹配。
class Solution:
def str2tree(self, s: str) -> Optional[TreeNode]:
index = 0
def helper():
nonlocal index
if index >= len(s):
return None
neg = False
if s[index] == '-':
neg = True
index += 1
num = 0
while index < len(s) and s[index].isdigit():
num = num * 10 + int(s[index])
index += 1
if neg:
num = -num
node = TreeNode(num)
if index < len(s) and s[index] == '(':
index += 1
node.left = helper()
if index < len(s) and s[index] == '(':
index += 1
node.right = helper()
#remove ')'
index += 1
return node
return helper()
return res