题目描述
给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。
示例 1:
输入:inorder = [9,3,15,20,7], postorder = [9,15,7,20,3]
输出:[3,9,20,null,null,15,7]
示例 2:
输入:inorder = [-1], postorder = [-1]
输出:[-1]
提示:
- 1 <= inorder.length <= 3000
- postorder.length == inorder.length
- -3000 <= inorder[i], postorder[i] <= 3000
- inorder 和 postorder 都由 不同 的值组成
- postorder 中每一个值都在 inorder 中
- inorder 保证是树的中序遍历
- postorder 保证是树的后序遍历
解题思路
二叉树的话基本想法还是递归了,后序遍历的最后一个元素是根节点,找到根节点在中序遍历中的位置,然后就可以分割出左子树和右子树的中序遍历和后序遍历。如此递归构建一颗二叉树。
1 | /** |
这里的思路是先找到根节点,然后通过一个 map
来记录左子树的节点,方便在后序遍历中找到右子树的起始位置。这样就可以递归地构建二叉树。
看了题解后发现还有一种思路可以不使用 map
,每次只分割出中序遍历的左右子树,然后优先构建右子树,这样就可以直接使用后序遍历的最后一个元素作为根节点。
1 | /** |
这里代码更加简洁,直接在递归函数中处理后序遍历的数组,不需要额外的 map
来记录左子树的节点。每次递归时,先构建右子树,再构建左子树,这样就可以直接使用后序遍历的最后一个元素作为根节点(使用最后一个元素后去除该元素)。
更进一步,避免每次递归都需要遍历 inorder
数组来找到根节点的位置,可以使用一个 map
来记录中序遍历中每个元素的索引,这样可以在 O(1) 的时间复杂度内找到根节点的位置。
1 | func buildTree(inorder []int, postorder []int) *TreeNode { |