Leetcode题解——构造二叉树

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

 

# 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, preorder: List[int], inorder: List[int]) -> TreeNode:
	    if not (preorder and inorder):
		    return None
		# 根据前序数组的第一个元素,就可以确定根节点	
	    root = TreeNode(preorder[0])
		# 用preorder[0]去中序数组中查找对应的元素
	    mid_idx = inorder.index(preorder[0])
		# 递归的处理前序数组的左边部分和中序数组的左边部分
		# 递归处理前序数组右边部分和中序数组右边部分
	    root.left = self.buildTree(preorder[1:mid_idx+1],inorder[:mid_idx])
	    root.right = self.buildTree(preorder[mid_idx+1:],inorder[mid_idx+1:])
	    return root

 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 not (inorder and postorder):
            return None
        def helper(inor,post):
            if not post:
                return None
            # 根据后序数组的最后一个元素,创建根节点    
            root = TreeNode(post[-1])
            # 在中序数组中查找值等于【后序数组最后一个元素】的下标
            idx = inor.index(post[-1])
            # 确定这个下标i后,将中序数组分成两部分,后序数组分成两部
            # 递归处理中序数组左边,后序数组左边
            # 递归处理中序数组右边,后序数组右边
            root.left = helper(inor[:idx],post[:idx])
            root.right = helper(inor[idx+1:],post[idx:-1])
            return root
        return helper(inorder,postorder)

 

 

class Solution(object):
    def buildTree(self, inorder, postorder):
        if not (inorder and postorder):
            return None
        # 将中序数组的下标、值保存到map中省去解法一中线性查找
        d = {val:idx for idx,val in enumerate(inorder)}
        self.post_idx = len(postorder)-1
        def dfs(left,right):
            if left>right:
                return None
            # 从后序数组中拿最后一个元素,根据这个元素去map中找到中序数组对应的index
            # 然后递归的处理右边[index+1,right],递归处理左边[left,index-1]
            val = postorder[self.post_idx]
            self.post_idx -= 1
            root = TreeNode(val)
            index = d[val]
            root.right = dfs(index+1,right)
            root.left = dfs(left,index-1)
            return root
        return dfs(0,len(inorder)-1)

889. 根据前序和后序遍历构造二叉树

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def constructFromPrePost(self, pre: List[int], post: List[int]) -> TreeNode:
        def dfs(pre,post):
            if not pre:
                return None
            # 数组长度为1时,直接返回即可
            if len(pre)==1:
                return TreeNode(pre[0])
            # 根据前序数组的第一个元素,创建根节点     
            root = TreeNode(pre[0])
            # 根据前序数组第二个元素,确定后序数组左子树范围
            left_count = post.index(pre[1])+1
            # 递归执行前序数组左边、后序数组左边
            root.left = dfs(pre[1:left_count+1],post[:left_count])
            # 递归执行前序数组右边、后序数组右边
            root.right = dfs(pre[left_count+1:],post[left_count:-1])
            # 返回根节点
            return root
        return dfs(pre,post)

 最后,再来看一道实例题,看笔试中的构建完整版:

 

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

def build(preorder, inorder):
    if not preorder:
        return None
    root = TreeNode(preorder[0])
    mid_idx = inorder.index(preorder[0])

    root.left = build(preorder[1:mid_idx + 1], inorder[:mid_idx])
    root.right = build(preorder[mid_idx + 1:], inorder[mid_idx + 1:])
    return root

def count(root):
    if root == None:
        return 0
    elif root.left == None and root.right == None:
        return 1
    else:
        return count(root.left) + count(root.right)

if __name__ == '__main__':
    N = map(int, input().strip().split())

    pre = list(map(int, input().strip().split()))
    inor = list(map(int, input().strip().split()))
    r = build(pre, inor)
    print(count(r))

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值