一、题目
根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
中序遍历 inorder = [9,3,15,20,7]
后序遍历 postorder = [9,15,7,20,3]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
二、递归解法
1. 解题思路
回忆中序遍历和后序遍历的过程:
- 中序遍历:左、根、右
- 后序遍历:左、右、根
- 参考经典问题剖析-由前序、中序遍历序列构造二叉树,希望你看了之后这道题不用看答案写出来
2. 编码
示例代码:
class BTreeNode(val value: Int) {
var left: BTreeNode? = null
var right: BTreeNode? = null
}
fun buildBTreeByInOrderAndPostOrder(inOrder: IntArray, postOrder: IntArray): BTreeNode? {
val inOrderIndexHashMap = mutableMapOf<Int, Int>()
inOrder.forEachIndexed { index, data ->
inOrderIndexHashMap[data] = index
}
return buildBTreeNodeByInOrderAndPostOrder(postOrder, inOrderIndexHashMap, 0, inOrder.size - 1, 0, postOrder.size - 1)
}
fun buildBTreeNodeByInOrderAndPostOrder(postOrder: IntArray, indexMap: MutableMap<Int, Int>, inLeft: Int, inRight: Int, postLeft: Int, postRight: Int): BTreeNode? {
if (inLeft > inRight) {
return null
}
//根节点
val root = BTreeNode(postOrder[postRight])
//通过跟节点的value值找在inOrder中的index
val index = indexMap[postOrder[postRight]] ?: return null
//找左子树的在preOrder和inOrder中的左右index
//左子树 在inOrder中的左右index
val leftChildTreeOnInOrderIndexLeft = inLeft
val leftChildTreeOnInOrderIndexRight = index -1
//左子树 在postOrder中的左右index
val leftChildTreeOnPostOrderIndexLeft = postLeft
val leftChildTreeOnPOstOrderIndexRight = index - 1 - inLeft + postLeft
//右子树 在inOrder中的左右index
val rightChildTreeOnInOrderIndexLeft = index + 1
val rightChildTreeOnInOrderIndexRight = inRight
//右子树 在postOrder中的左右index
val rightChildTreeOnPostOrderIndexLeft = index - 1 - inLeft + postLeft + 1
val rightChildTreeOnPostOrderIndexRight = postRight - 1
root.right = buildBTreeNodeByInOrderAndPostOrder(postOrder, indexMap, rightChildTreeOnInOrderIndexLeft, rightChildTreeOnInOrderIndexRight, rightChildTreeOnPostOrderIndexLeft, rightChildTreeOnPostOrderIndexRight)
root.left = buildBTreeNodeByInOrderAndPostOrder(postOrder, indexMap, leftChildTreeOnInOrderIndexLeft, leftChildTreeOnInOrderIndexRight, leftChildTreeOnPostOrderIndexLeft, leftChildTreeOnPOstOrderIndexRight)
return root
}
3. 时空复杂度
时间复杂度:数组中每个值都要访问构建二叉树节点,所以时间复杂度为O(n)
空间复杂度:使用Hash表存储根节点的index,需要O(n)的空间
三、总结
- 此题难度中等
- 经典题目,关键是找到根节点、左、右子树在前序、中序序列中的index、leftIndex、rightIndex即可
leetcode传送门:106. 从中序与后序遍历序列构造二叉树