106从中序与后序遍历序列构造二叉树

题目: 根据一棵树的中序遍历与后序遍历构造二叉树.

来源: https://leetcode-cn.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/

法一: 模仿105方法

思路: index设置为全局变量,依次从后序遍历中取一个元素,用该元素来分割中序遍历list.确定每次递归的左子树和右子树.优点是用到内存小,每次当left==right时,说明左子树或右子树为空了,返回None.

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
# 执行用时 :60 ms, 在所有 python3 提交中击败了98.47% 的用户
# 内存消耗 :17.1 MB, 在所有 python3 提交中击败了96.25%的用户
from typing import List
class Solution:
    def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
        # 这里反序的目的是为了模仿105中的方法,前序是中左右,后序是左右中,反序后即为中右左
        postorder.reverse()
        index = 0
        def recursion(left=0,right=len(inorder)):
            # 这里实际上将index设置成了全局变量
            nonlocal index
            if left == right:
                return None
            root_val = postorder[index]
            root = TreeNode(root_val)
            k = index_map[root_val]
            index += 1
            # 这里的关键是确定递归的范围,要通过写例子来确定
            root.right = recursion( left=k+1, right=right)
            root.left = recursion( left, right= k)
            return root
        index_map = {element:index for index,element in enumerate(inorder)}
        return recursion()
if __name__ == '__main__':
    duixiang = Solution()
    # inorder = [8, 4, 9, 2, 10, 5, 1, 6, 3, 13, 11, 14, 7, 12]
    # postorder = [8, 9, 4, 10, 5, 2, 6, 13, 14, 11, 12, 7, 3, 1]
    inorder = [1,2]
    postorder = [2,1]
    a = duixiang.buildTree(inorder=inorder, postorder=postorder)
    print(a)
View Code

法二: 模仿889方法

思路: 仍然是每次从后序遍历中取第一个元素,不同的是后序遍历的list每次都不同,每次都是用切片传list.缺点是内存消耗大.

# Definition for a binary tree node.
class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None
# 执行用时 :220 ms, 在所有 python3 提交中击败了50.63% 的用户
# 内存消耗 :87.3 MB, 在所有 python3 提交中击败了72.50%的用户
# 这个方法模仿889从前序和后序遍历构造二叉树
class Solution:
    def buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
        postorder.reverse()
        def recursion(inorder=inorder, postorder=postorder):
            # 有可能某个节点的左子树或右子树为空,直接返回None
            if len(inorder) == 0: return None
            root = TreeNode(postorder[0])
            # 如果长度为1了,说明其没有左子树和右子树了,直接返回
            if len(postorder) == 1:
                return root
            # 求节点在中序遍历中的索引
            L = inorder.index(root.val)
            size = len(inorder)
            # 这里的关键是确定递归的范围,要通过写例子来确定
            root.right = recursion( inorder[L+1:], postorder[1:size-L])
            root.left = recursion( inorder[:L], postorder[-L:])
            return root
        return recursion()
if __name__ == '__main__':
    duixiang = Solution()
    # inorder = [8, 4, 9, 2, 10, 5, 1, 6, 3, 13, 11, 14, 7, 12]
    # postorder = [8, 9, 4, 10, 5, 2, 6, 13, 14, 11, 12, 7, 3, 1]
    inorder = [1,2]
    postorder = [2,1]
    a = duixiang.buildTree(inorder=inorder, postorder=postorder)
    print(a)
View Code

posted on 2019-12-19 22:56  吃我一枪  阅读(264)  评论(0编辑  收藏  举报

导航