题目描述
题解
思路:
首先要了解前序遍历preorder(根左右),中序遍历inorder(左根右)。
所以想到,整个树的根节点肯定就是preorder的第一个数—> [根 | 左右 ]。确定了整个树的根之后,看到中序遍历,咦,不久能把左子树的点和右子树的点切开了吗?----> [左 | 根 | 右](注意题目有个说明,树中没有重复的元素)。
到这里,已经得到左子树和右子树的中序遍历列表了,如果我再得到左子树和右子树的前序遍历,不就能使用递归,然后构造了吗?
那么如何切分 前序遍历 的左和右呢?这里就想到了 虽然和中序遍历的顺序不一样,但是元素的个数肯定是一样的呀!所以就用个数来划分。
上代码
# 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:
if not preorder: # 递归的终止条件
return None
root = TreeNode(preorder[0]) # 定义根结点
rootIndex = inorder.index(preorder[0]) # 找到中序遍历列表中,根结点的位置
leftInorder = inorder[:rootIndex] # 根据根结点的位置,切割左子树
rightInorder = inorder[rootIndex+1:] # 切割右子树
leftNum = len(leftInorder) # 计算左子树的结点个数
leftPreorder = preorder[1:1+leftNum] # 切割前序遍历的左子树
rightPreorder = preorder[1+leftNum:] # 切割前序遍历的右子树
root.left = self.buildTree(leftPreorder, leftInorder) # 利用递归重构左子树
root.right = self.buildTree(rightPreorder, rightInorder) # 利用递归重构右子树
return root
总结: 二叉树真的非常喜欢递归啊,因为二叉树太具有对称性和规律了。