题目
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
思路
对于任意一棵树而言,
前序遍历的形式:[根节点,[左子树的前序遍历],[右子树的前序遍历]];
中序遍历的形式:[[左子树的中序遍历],根节点,[右子树的中序遍历]];
前序遍历和中序遍历的长度相同,所以可以根据前序遍历定位根节点,根据中序遍历的根节点索引找到根节点左子树的长度,从而可以定位前序遍历的左子树与右子树的分界点。
这样我们可以递归的构造出左右子树,再将这两棵子树接到根节点左右。
使用哈希映射帮助快速定位根节点。
#前序遍历的形式:[根节点,[左子树的前序遍历],[右子树的前序遍历]];
#中序遍历的形式:[[左子树的中序遍历],根节点,[右子树的中序遍历]];
# 时间复杂度:O(N)
# 空间复杂度:O(N)
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
def mybuildTree(pre_left, pre_right, in_left, in_right):
if pre_left>pre_right:
return None
# 前序遍历的根节点索引为前序遍历序列的第一个
pre_root = pre_left
# 找到中序遍历的根节点索引
in_root = hash_in[preorder[pre_root]]
# 构建根节点, root = TreeNode(val)
root = TreeNode(preorder[pre_root])
# 左子树长度
len_left = in_root - in_left
# 构建左子树
root.left = mybuildTree(pre_root+1, pre_root+len_left, in_left, in_root-1)
# 构建右子树
root.right = mybuildTree(pre_root+len_left+1, pre_right, in_root+1, in_right)
return root
n = len(preorder)
hash_in = {val:i for i, val in enumerate(inorder)}
return mybuildTree(0, n-1, 0, n-1)