leetcode 105.从前序与中序遍历序列构造二叉树 python 剑指offer系列 4 面试题07. 重建二叉树

leetcode 105.从前序与中序遍历序列构造二叉树

  • 题目描述
  • 题解

题目描述

leetcode 105.从前序与中序遍历序列构造二叉树 python 剑指offer系列 4 面试题07. 重建二叉树_第1张图片

题解

思路:
首先要了解前序遍历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

总结: 二叉树真的非常喜欢递归啊,因为二叉树太具有对称性和规律了。

你可能感兴趣的:(刷题)