leetcode1028. 从先序遍历还原二叉树
我们从二叉树的根节点 root
开始进行深度优先搜索。
在遍历中的每个节点处,我们输出 D 条短划线(其中 D 是该节点的深度),然后输出该节点的值。(如果节点的深度为 D,则其直接子节点的深度为 D + 1。根节点的深度为 0)。
如果节点只有一个子节点,那么保证该子节点为左子节点。
给出遍历输出 S
,还原树并返回其根节点 root
。
示例 1:
输入:"1-2--3--4-5--6--7"
输出:[1,2,5,3,4,6,7]
示例 2:
输入:"1-2--3---4-5--6---7"
输出:[1,2,5,3,null,6,null,4,null,7]
示例 3:
输入:"1-401--349---90--88"
输出:[1,401,null,349,88,90]
提示:
- 原始树中的节点数介于
1
和1000
之间。 - 每个节点的值介于
1
和10 ^ 9
之间。
方法:哈希表
思路:
我们首先考虑先序遍历的特点,先根节点→左子树→右子树。这样的顺序也就意味着,同一层的结点,一定是最左边的先遍历到,最右边的后遍历到;且遍历到同一层的第二个结点时,这一层第一个结点的左右子树已经遍历完了,第一个结点就不需要再更改了,因此我们每次,每一层只需要保留一个该层的结点即可。
我们使用哈希表tree_dic来保存每一层当前遍历到的结点,键为深度,值为树结点,根节点的键为0。然后开始遍历字符串S,根据’-'的数量计算这个节点的深度depth,获得这个结点的值value。因为子节点比父节点的深度大1,且题目说,如果节点只有一个子节点,那么保证该子节点为左子节点,只要判断此时depth-1层的结点tree_dic[depth-1]的左结点是否存在,存在的话,把当前的节点连接到它的右子节点上,不存在的话连接到左子节点上;然后将tree_dic[depth]更新为当前节点即可。
最后返回tree_dic[0],即根节点,如果根节点不存在,返回None。
代码:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def recoverFromPreorder(self, S: str) -> TreeNode:
#初始化字典,键为层数,值为该层目前遍历到的最后一个结点
tree_dic = dict()
i = 0
while i < len(S):
depth = 0
value = ''
while i < len(S) and S[i] == '-':
depth += 1
i += 1
while i < len(S) and S[i].isdigit():
value += S[i]
i += 1
#此时depth为这个节点的深度,value为这个节点的值(str形式)
#生成节点
node = TreeNode(int(value))
if depth > 0:
#判断此时,比它深度少1的结点有没有左结点,没有就连上,有就作为右结点
if tree_dic[depth-1].left:
tree_dic[depth-1].right = node
else:
tree_dic[depth-1].left = node
#更新这个深度的最后一个节点为node
tree_dic[depth] = node
#最后返回根节点
return tree_dic[0] if tree_dic[0] else None