leetcode日记

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

2020-11-22  本文已影响0人  半匣烛火

一、题目

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

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
    3
   / \
  9  20
    /  \
   15   7

二、递归解法

1. 解题思路

清楚前序遍历和中序遍历的过程:

前序、中序序列分割图

2. 编码

由解题思路,很容易写出此题的递归解法代码。
示例代码:

class BTreeNode(val value: Int) {
    var left: BTreeNode? = null
    var right: BTreeNode? = null
}

fun buildBTreeByPreOrderAndInOrder(preOrder: IntArray, inOrder: IntArray): BTreeNode? {
    val inOrderIndexHashMap = mutableMapOf<Int, Int>()
    inOrder.forEachIndexed { index, data ->
        inOrderIndexHashMap[data] = index
    }
    return buildBTreeNode(preOrder, inOrderIndexHashMap, 0, preOrder.size - 1, 0, inOrder.size - 1)
}

fun buildBTreeNode(preOrder: IntArray, indexMap: MutableMap<Int, Int>, preOrderLeft: Int, preOrderRight: Int, inOrderLeft: Int, inOrderRight: Int): BTreeNode? {
    if (preOrderLeft > preOrderRight) {
        return null
    }
    //根节点
    val root = BTreeNode(preOrder[preOrderLeft])
    //通过跟节点的value值找在inOrder中的index
    val index = indexMap[preOrder[preOrderLeft]] ?: return null
    //找左子树的在preOrder和inOrder中的左右index

    //左子树 在preOrder中的左右index
    val leftChildTreeOnPreOrderIndexLeft = preOrderLeft + 1
    val leftChildTreeOnPreOrderIndexRight = index - inOrderLeft + preOrderLeft
    //左子树 在inOrder中的左右index
    val leftChildTreeOnInOrderIndexLeft = inOrderLeft
    val leftChildTreeOnInOrderIndexRight = index - 1


    //右子树 在preOrder中的左右index
    val rightChildTreeOnPreOrderIndexLeft = leftChildTreeOnPreOrderIndexRight + 1
    val rightChildTreeOnPreOrderIndexRight = preOrderRight
    //右子树 在inOrder中的左右index
    val rightChildTreeOnInOrderIndexLeft = index + 1
    val rightChildTreeOnInOrderIndexRight = inOrderRight

    root.left = buildBTreeNode(preOrder, indexMap, leftChildTreeOnPreOrderIndexLeft, leftChildTreeOnPreOrderIndexRight, leftChildTreeOnInOrderIndexLeft, leftChildTreeOnInOrderIndexRight)
    root.right = buildBTreeNode(preOrder, indexMap, rightChildTreeOnPreOrderIndexLeft, rightChildTreeOnPreOrderIndexRight, rightChildTreeOnInOrderIndexLeft, rightChildTreeOnInOrderIndexRight)
    return root
}

3. 时空复杂度分析

时间复杂度:数组中每个值都要访问构建二叉树节点,所以时间复杂度为O(N)
空间复杂度:使用Hash表存储根节点的index,需要O(N)的空间,最多有O(logN)个函数调用,所以空间复杂度是O(N)

四、总结

leetcode传送门:105. 从前序与中序遍历序列构造二叉树

上一篇 下一篇

猜你喜欢

热点阅读