《Leetcode of September 》106. 从中序与后序遍历序列构造二叉树

 

# 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, inorder: List[int], postorder: List[int]) -> TreeNode:
        if len(postorder)==0:
            return None

        #优化后,递归传入的只是下标而不是数组,大大减少了内存消耗
        def helper(in_left, in_right):
            # 如果这里没有节点构造二叉树了,就结束
            if in_left > in_right:
                return None
            
            # 选择 post_idx 位置的元素作为当前子树根节点
            val = postorder.pop()
            root = TreeNode(val)

            # 根据 root 所在位置分成左右两棵子树
            index = idx_map[val]

           
            #一定是先构造右子树的,因为后序遍历是[左|右|中]
            # 构造右子树
            root.right = helper(index + 1, in_right)
            
            # 构造左子树
            root.left = helper(in_left, index - 1)
            return root
        
        # 建立(元素,下标)键值对的哈希表,使用O(1)的时间复杂度进行中序序列的查询
        idx_map = {val:idx for idx, val in enumerate(inorder)} 
        return helper(0, len(inorder) - 1)


        #优化之前
        val = postorder[-1]
        index = inorder.index(val)
        root = TreeNode(val)
        
        #创建左子树
        root.left = self.buildTree(inorder[:index],postorder[:index])
        
        #创建右子树
        root.right = self.buildTree(inorder[index+1:],postorder[index:-1])

        return root

总结:这个题目我会,本科的时候学习数据结构的时候老师就在黑板让实现过,根据中序和后序就可以确定出来一颗二叉树,但是没有实现过代码,当然这个题目和重建二叉树是如出一辙的,这个题目是已知前序和中序重构一个二叉树。

可以确定一个思路就是肯定用递归来做。那么从后序遍历来确定根节点,一旦确定根节点,就可以把中序遍历划分成左右两个子树,也可以把后序遍历划分成左右两个子树,然后递归的构建根节点的左子树和根节点的右子树。中序遍历【左|根|右】,后序遍历【左|右|根】。一旦确定新划分的左右子树序列,那就非常好容易做了。但是每次去查询根节点在中序遍历中的位置非常的耗时,基本都是O(n),因此时间复杂度比较高,我们可以把中序遍历hash化,这样查找的效率就提高了非常多。

©️2020 CSDN 皮肤主题: 创作都市 设计师:CSDN官方博客 返回首页