美文网首页leetcode日记
经典问题剖析-由中序、后序遍历序列构造二叉树(java/kotl

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

作者: 半匣烛火 | 来源:发表于2020-11-22 16:27 被阅读0次

    一、题目

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

    例如,给出

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

    相关文章

      网友评论

        本文标题:经典问题剖析-由中序、后序遍历序列构造二叉树(java/kotl

        本文链接:https://www.haomeiwen.com/subject/bmiuiktx.html