【leetcode】105. Construct Binary Tree from Preorder and Inorder Traversal

给定二叉树的前序遍历和中序遍历,让构建这棵树二叉树。
思路:
以题目给的例子为例
preorder = [3,9,20,15,7]
inorder = [9,3,15,20,7]
因为先序遍历是先访问根节点,再访问左右子树,所以先序遍历出现的第一个节点一定是整棵树的跟节点,所以3是根节点。
这样我们可以把中序遍历的数组根据根节点分成两个部分,左子树和右子树
left child = [9]
right_child =[15,20,7]
因为左子树就一个节点,所以没啥好说的,来看右子树。访问前序遍历访问右子树时,第一个访问的肯定是右子树的根节点,也就是说left_child中的元素,第一次出现在先序遍历数组中的一定是右子树的根节点。
这样我们又选出了一个根节点,将右子树分成了两部分,跟先前的问题一样,所以可以递归的去解决。
过程:
preorder_dict这个map来保存前序遍历中每个元素和他们对应的数组下标,这样方便后面找第一次出现的元素(下标最小的即为第一次出现的)。
start,end来标记inorder数组中当前子树对应的元素首尾的位置

class TreeNode:
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution:
    def buildTree(self, preorder, inorder):
        """
        :type preorder: List[int]
        :type inorder: List[int]
        :rtype: TreeNode
        """
        self.preorder_dict={}
        for i in range(len(preorder)):
            self.preorder_dict[preorder[i]] = i
        self.inorder = inorder
        root = self.helper(0,len(inorder)-1)
        return root

    def helper(self,start, end):
        #start:end+1 inorder
        if start > end:
            return None

        root_index_in_inorder = -1
        root_index_in_preorder = float("inf")
        for i in range(start,end+1):
            if root_index_in_preorder > self.preorder_dict[self.inorder[i]]:
                root_index_in_preorder = self.preorder_dict[self.inorder[i]]
                root_index_in_inorder = i
        root = TreeNode(self.inorder[root_index_in_inorder])
        root.left =self.helper(start, root_index_in_inorder-1)
        root.right =self.helper(root_index_in_inorder+1, end)
        return root

顺便说一下,由中序和后续构建二叉树跟这个几乎是一模一样的思路,唯一不同是,给前序中序时,我们从前序里找跟节点是找第一个出现的,而给后续中序时,从后续找根节点是找最后一个出现的。
这样,另外一道题也能迎刃而解了

精简一下代码

class Solution:
    def buildTree(self, preorder, inorder):
        """
        :type preorder: List[int]
        :type inorder: List[int]
        :rtype: TreeNode
        """
        self.dictionary = {}
        for index, value in enumerate(preorder):
            # print(index,value)
            self.dictionary[value] = index
        return self.construct(inorder, 0, len(inorder)-1)

    def construct(self, inorder, start, end):
        if start > end:
            return
        tmp = float("inf")
        root_index = -1
        for i in range(start, end+1):
            if tmp > self.dictionary[inorder[i]]:
                tmp = self.dictionary[inorder[i]]
                root_index = i
        root = TreeNode(inorder[root_index])
        root.left = self.construct(inorder, start, root_index-1)
        root.right = self.construct(inorder, root_index+1, end)
        return root

你可能感兴趣的:(LeetCode)