LeetCode每日一题,106. Construct Binary Tree from Inorder and Postorder Treversal
先看题目描述
大意就是给定一棵二叉树的中序遍历序列和后序遍历序列,让我们将二叉树还原
算法和思路
我们得先了解中序遍历和后序遍历,中序遍历就是对一棵二叉树按左根右的顺序遍历,后序遍历就是对一棵二叉树按左右根的顺序进行遍历。由这个遍历顺序我们不难发现,一棵树的后序遍历序列中的最后一个节点就是根节点,而中序遍历序列中根节点会在中间部分,根节点的的左边部分是其左子树的所有节点,右边部分是其右子树的所有节点。那么我们就可以先根据后序遍历序列找出树的根节点,然后根据中序遍历序列将左子树和右子树的所有节点找出来,并可得到他们的中序遍历序列和后序遍历序列,然后再递归的构建左子树和右子树就可以
算法源码
1 | /** |
但这个的效率并不优秀,因为每次要重复的遍历中序遍历序列来寻找根节点下标
定义一个变量 post_idx,初始化为 n - 1,表示后序遍历序列中当前根节点所在下标
为了高效查找根节点元素在中序遍历数组中的下标,我们可以创建哈希表来存储中序序列
定义递归函数 dfs(left, right) 表示当前递归到中序序列中当前子树的左右边界,递归入口为 dfs(0, n - 1) :
- 计算 [left, right] 区间的长度 len
- 如果 len 与 0相等,直接返回空节点
- 选择后序遍历中下标为 post_idx 的节点作为根节点
- post_idx = post_idx - 1
- 利用哈希表查找当前根节点在中序遍历序列中的下标 index,[0, index - 1] 为左子树部分,[index + 1, right] 为右子树部分
- 根据后序遍历逻辑,递归创建右子树 dfs(index + 1, right) 和左子树 dfs(left, index - 1)。注意这里有需要先创建右子树,再创建左子树的依赖关系。可以理解为在后序遍历的数组中整个数组是先存储左子树的节点,再存储右子树的节点,最后存储根节点,如果按每次选择「后序遍历的最后一个节点」为根节点,则先被构造出来的应该为右子树
- 返回 root
1 | import java.util.*; |