# 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化,这样查找的效率就提高了非常多。