经典问题剖析-由中序、后序遍历序列构造二叉树

一、题目

根据一棵树的中序遍历与后序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。

例如,给出

中序遍历 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. 从中序与后序遍历序列构造二叉树

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值