首页 > 其他 > 详细

剑指 Offer 07. 重建二叉树重建二叉树

时间:2020-08-05 00:08:50      阅读:103      评论:0      收藏:0      [点我收藏+]
  • 题目描述

输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

例如,给出

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:

3
/ \
9 20
/ \
15 7
 

限制:

0 <= 节点个数 <= 5000

  • 分析

首先我们需要了解下二叉树的前序遍历和中序遍历的特点

前序遍历: 节点按照 [ 根节点 | 左子树 | 右子树 ] 排序,以题目示例为例:[ 3 | 9 | 20 15 7 ]

中序遍历: 节点按照 [ 左子树 | 根节点 | 右子树 ] 排序,以题目示例为例:[ 9 | 3 | 15 20 7 ]

那么可以得到:

前序遍历的第一个元素即为root节点

可根据这个root找到中序遍历中左子树和右子树的:[ 左子树 | 根节点 | 右子树 ]

根据中序遍历的左右子树的节点数量,可将前序遍历划分为[ 根节点 | 左子树 | 右子树 ]

根据子树特点,我们可以通过同样的方法对左(右)子树进行划分,每轮可确认三个节点的关系 。此递推性质让我们联想到用 递归方法 处理。

参照题解:https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/solution/mian-shi-ti-07-zhong-jian-er-cha-shu-di-gui-fa-qin/

 

此时需要理解的是:

            preorder_left:前序遍历的起始坐标
            preorder_right:前序遍历的终止坐标
            inorder_left:中序遍历的起始坐标
            inorder_right:中序遍历的终止坐标
此时递归的左子树
class Solution:
    ‘‘‘
    哈希表+递归
    ‘‘‘
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        rootCan = {}
        if not preorder:
            return None
        for i in range(len(inorder)):
            rootCan[inorder[i]] = i
        
        def build(preorder_left, preorder_right, inorder_left, inorder_right):
            ‘‘‘
            preorder_left:前序遍历的起始坐标
            preorder_right:前序遍历的终止坐标
            inorder_left:中序遍历的起始坐标
            inorder_right:中序遍历的终止坐标
            ‘‘‘
            if preorder_left > preorder_right:
                return None
            root = preorder[preorder_left] #前向遍历查找根节点
            root_inder_inorder = rootCan[root] #根节点在中序遍历中的索引
            order_num = root_inder_inorder - inorder_left #左子树长度
            node = TreeNode(root)
            #前序遍历中左子树的边界是[preorder_left + 1, preorder_left + order_num],中序遍历左子树的边界的[inorder_left, inorder_left + order_num - 1]
#前序遍历中右子树的边界是[preorder_left + 1 + order_num, preorder_right],中序遍历右子树边界是[inorder_left + order_num + 1, inorder_right]
            node.left = build(preorder_left + 1, preorder_left + order_num, inorder_left, inorder_left + order_num - 1) #左子树 
node.right
= build(preorder_left + 1 + order_num, preorder_right, inorder_left + order_num + 1, inorder_right) #右子树

return node
root
= build(0, len(preorder)-1, 0, len(preorder)-1)

return root

或者不用哈希表,就用数组递归:

首先呢还是需要查找前序遍历的root节点在中序遍历中的位置,然后根据这个位置,可以前序遍历和中序遍历中的左右子树找出来。然后分别调用自身进行递归。

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 len(preorder) == 0:#此时连根节点都没有 ,递归结束条件
            return None
        root = preorder[0]
        current_root= inorder.index(root)
        tree = TreeNode(root)
        #减小规模
        left_pre = preorder[1:current_root+1]
        right_pre = preorder[current_root+1:]
        left_in = inorder[:current_root]
        right_in = inorder[current_root+1:]
        tree.left = self.buildTree(left_pre, left_in) #调用自身
        tree.right = self.buildTree(right_pre, right_in)
        return tree

 

剑指 Offer 07. 重建二叉树重建二叉树

原文:https://www.cnblogs.com/yeshengCqupt/p/13435807.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!