题目
思路
中序遍历:每次遍历左孩子,再遍历根节点,最后遍历右孩子。
后序遍历:每次
后序遍历最后一个元素为根节点root;
由根节点root可以将中序遍历分为树的left、right。
由此可知,使用递归方法。
为了避免每次花费时间查找inorder数组中的索引,使用一个hash表提前存储所有节点在inorder数组中的索引,用空间换取时间。
# 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:
root_index = {val : idx for idx, val in enumerate(inorder)}
def helper(left, right):
# 当左边界 > 右边界,无法构造左右子树,结束
if left > right:
return None
val = postorder.pop() # 后序遍历最后一个元素为当前子树的根节点的值
root = TreeNode(val) # 初始化节点
idx = root_index[val] # 找到val在中序遍历中的位置
# 根据root,将中序遍历分为左子树、右子树
# root.left = helper(left, idx - 1)
root.right = helper(idx + 1, right)
root.left = helper(left, idx - 1)
return root
return helper(0, len(inorder) - 1) # 中序遍历的左边界0和右边界len(inorder) - 1
有坑?
如果先构建左子树,代码就不对了。
因为根节点是通过后序排列的back确定的,后序的顺序是left(a) right(b) root(c),所以下一次的back(b)应该是属于root的右子树的