题目链接
https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
题目描述
根据一棵树的前序遍历和中序遍历构造二叉树。二叉树中不包含重复元素。
示例
输入:preorder=[3,9,8,6,7],inorder = [9,3,6,8,7]
输出: [3,9,8,null,null,6,7]
解题思路
这道题首先需要根据前序遍历和中序遍历的结果找到根节点,然后找出左右子树的前序、中序遍历结果,递归构建左右子树。
首先根据前序遍历结果preorder得到树的根节点preorder[0],然后在中序遍历结果inorder中找到值等于preorder[0]的元素索引,设为x,那么inorder[0,...,x-1](左闭右闭区间)为左子树的中序遍历结果,inorder[x+1:]为右子树的中序遍历结果。同时我们也知道了左子树共有x个节点,因此preorder[1:x](左闭右闭区间)为左子树的前序遍历结果,preorder[x+1:]为右子树的前序遍历结果。
Python实现
下面代码中维护[pre_lo,pre_hi]为子树的前序遍历结果区间,[in_lo,in_hi]为中序遍历结果区间。在传递索引时要记住我们找的是左闭右闭区间。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
def construct(preorder,pre_lo,pre_hi,inorder,in_lo,in_hi):
#用左闭右闭区间
if(pre_lo > pre_hi or in_lo > in_hi):
return None
root_value = preorder[pre_lo]#根节点的值
#找到根节点在中序遍历中的位置,index()方法时间复杂度为O(1),返回列表中第一次该元素出现的位置
root_index = inorder.index(root_value)
left_subtree_num = root_index-in_lo
root = TreeNode(root_value)
root.left = construct(preorder,pre_lo+1,pre_lo+left_subtree_num,inorder,in_lo,root_index-1)
root.right = construct(preorder,pre_lo+left_subtree_num+1,pre_hi,inorder,root_index+1,in_hi)
return root
root = construct(preorder,0,len(preorder)-1,inorder,0,len(inorder)-1)
return root
还可以利用Python中的切片传递子树的前序遍历和中序遍历结果。注意切片nums[x:y]取的是[x,y)左闭右开区间。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
def construct(preorder,inorder):
#如果用来构建子树的前序中序遍历结果为空,则返回None
if not preorder or not inorder:
return None
root_value = preorder[0]#根节点的值
#找到根节点在中序遍历中的位置,index()方法时间复杂度为O(1),返回列表中第一次该元素出现的位置
root_index = inorder.index(root_value)
left_subtree_num = root_index
root = TreeNode(root_value)
root.left = construct(preorder[1:left_subtree_num+1],inorder[0:root_index])
root.right = construct(preorder[left_subtree_num+1:],inorder[root_index+1:])
return root
root = construct(preorder,inorder)
return root