输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
思路:首先通过先序遍历序列可以得到树的根节点,然后在中序序列中找到根节点的位置,则以根节点为界限,向左到0,为左子树,向右到len() - 1 位右子树,然后得到的左右子树之后可以根据子树长度,在前序遍历中找到对应左右子树的边界,也就是能找到序列中对应左右子树的子序列。然后再对子序列进行上述操作,递归即可,终止条件为中序遍历序列中的左子树边界 >右子树边界。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
self.preorder = preorder
self.dic = {inorder[i]: i for i in range(len(inorder))} #将中序遍历序列构造为hashmap,键为node.val值为对应索引
return self.recur(0, 0, len(inorder) - 1)
def recur(self, pre_root_idx, in_left_idx, in_right_idx):
'''
pre_root_idx:前序遍历中的根节点
in_left_idx:中序遍历中的左子树边界
in_right_idx:中序遍历中的右子树边界
'''
if in_left_idx > in_right_idx:
return
root = TreeNode(self.preorder[pre_root_idx])
in_idx = self.dic[self.preorder[pre_root_idx]]
root.left = self.recur(pre_root_idx + 1, in_left_idx, in_idx - 1)
root.right = self.recur(in_idx - in_left_idx + pre_root_idx + 1, in_idx + 1, in_right_idx)
#in_idx - in_left_idx (左子树的长度) + pre_root_idx + 1 为右子树的根节点位置
return root