剑指offer 07 重建二叉树
**题目描述:**输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
解题思路:
在一棵二叉数的前序遍历结果中,容易得到根节点、即为第一个数。由于题目给的遍历结果中不含重复的数,所以在中序遍历中找到根节点,就可以将二叉树分为左子树和右子树。在前序遍历中,左子树的根是原二叉树的根加一,右子树的根可以根据左子树的长度计算,得到树的根后递归重复上述过程即可重建二叉树。递归函数中设置辅助参数left和right、作为中序遍历中子树的左右边界。
讲得比较简单,可结合代码注释理解
代码实现:
#python
# 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:
#第一个参数root在前序遍历中考虑;left、right是中序遍历中的边界,都是指序号
def recur(root,left,right):
if left > right: return #在递归过程中,left、right是要改变的
Node = TreeNode(preorder[root])
i = dic [preorder[root]] #得到中序中的序号
Node.left = recur(root+1,left,i-1)#第一个参数是作为preoder的索引;
#传入的left也是左子树的left;左子树的right是中序的root的左边,因为访问完左子树的所有元素才会访问root
Node.right = recur(root+i-left+1,i+1,right)
#右子树的根等于root加上左子树的长度(因为先序中是先遍历根,然后到左子树,再到右子树)
#而左子树的长度在在中序遍历中就是left到root之间的长度:i-left+1
#这里的i-1、i+1使得递归到一定的次数就终止、并回溯
return Node
dic = {}
preorder = preorder
for i in range(len(inorder)):
dic[inorder[i]] = i #将取值和对应的序号保存到字典中
return recur(0,0,len(inorder)-1)