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

  1. 题目链接

  2. 解题思路:首先我们得知道人工怎么建这棵树。先序遍历[0, R1]第一个节点,就是根。然后我们在中序遍历[0, R2]找到根的位置,假如是x,那么,中序遍历中[0, x-1]就是左子树,中序遍历中[x+1, R2]就是右子树。那么先序遍历呢?左子树节点个数是x个,先序遍历是要先遍历完左子树,才能到右子树,所以,先序遍历中,左子树的范围就是[1, x],右子树的范围就是[x+1, R1]。那左子树怎么构造?右子树怎么构造,递归调用创建即可。

    • 再抽象一点process(preorder, L1, R1, inorder, L2, R2),在preorder[L1, R1]inorder[L2, R2]上构造,那么头就是L1,然后递归调用,得到左子树process(preorder, L1 + 1, x - L2 + L1, inorder, L2, x - 1),递归调用,得到右子树process(preorder, x - L2 + L1 + 1, R1, inorder, x + 1, R2)
  3. 代码

    class Solution:
    
        # 从先序[L1, R1]和中序[L2, R2]构造二叉树
        def process(self, preorder: List[int], L1: int, R1: int, inorder: List[int], L2: int, R2: int) -> Optional[TreeNode]:
            if L1 > R1:
                return None
            if L1 == R1:
                return TreeNode(preorder[L1])
            # 这颗二叉树的头
            head = TreeNode(preorder[L1])
            # 在中序遍历中,找到头的位置
            head_index = -1
            for i in range(L2, R2 + 1):
                if head.val == inorder[i]:
                    head_index = i
                    break
            # [L2, head_index - 1]就是左子树   节点个数是head_index-L2
            # [head_index + 1, R2]就是右子树   节点个数是R2+head_index+2
    
            left_head = self.process(preorder, L1 + 1, head_index - L2 + L1, inorder, L2, head_index - 1)
            right_head = self.process(preorder, head_index - L2 + L1 + 1, R1, inorder, head_index + 1, R2)
            head.left = left_head
            head.right = right_head
            return head
        
        def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
            return self.process(preorder, 0, len(preorder) - 1, inorder, 0, len(inorder) - 1)
    
posted @ 2024-12-25 17:37  ouyangxx  阅读(29)  评论(0)    收藏  举报