[牛客算法总结]:重建二叉树

标签:

二叉树、DFS、先序遍历、中序遍历、递归

题目:

给定节点数为 n 的二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出如下图所示。

提示: 1.vin.length == pre.length 2.pre 和 vin 均无重复元素 3.vin出现的元素均出现在 pre里 4.只需要返回根结点,系统会自动输出整颗树做答案对比 数据范围:n le 2000n≤2000,节点的值 -10000 le val le 10000−10000≤val≤10000 要求:空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)

示例1

输入:[1,2,4,7,3,5,6,8],[4,7,2,1,5,3,8,6] 返回值:{1,2,3,4,#,5,6,#,7,#,#,8} 说明: 返回根节点,系统会输出整颗二叉树对比结果,重建结果如题面图示

示例2

输入:[1],[1] 返回值:{1}

反思:个人思考

由于二叉树的先序遍历:根左右、中序遍历:左根右可可以得出: 1、根节点为pre[0] 2、中序遍历中跟位置左边为左子树、右边为右子树 3、通过不断递归、我们可以得出每一个节点

具体思路 // root index = 1 // 先序遍历:[1,2,4,7,3,5,6,8] // 中序遍历:[4,7,2,1,5,3,8,6] // 具体思路是:先通过先序遍历的特点找到跟节点,然后通过跟节点来找到根节点在 // 中序遍历中的位置,然后根据中序遍历的特点(左根右),root左边的就是左子树的个数 // root右边的就是右子树的个数,根据这个特点来通过本方法找到root.left,root.right // 再通过递归,找到每一个节点。

用到的知识点:

二叉树、DFS、先序遍历、中序遍历、递归、Arrays.copyOfRange():左包右不包

代码:代码内容

public TreeNode reConstructBinaryTree(int [] pre, int [] vin) {
        if (pre == null || pre.length == 0) return null;
        // 构建具体的树根
        TreeNode root = new TreeNode(pre[0]);

        // 通过先序遍历和中序遍历来找到根节点在中序遍历的位置
        int index = findRootIndexInOrder(pre, vin);

        // 通过递归构建左子树
        root.left = reConstructBinaryTree(
                        Arrays.copyOfRange(pre, 1, index + 1),
                        Arrays.copyOfRange(vin, 0, index)
                    );
        // 通过递归构建右子树
        root.right = reConstructBinaryTree(
                         Arrays.copyOfRange(pre, index + 1, pre.length),
                         Arrays.copyOfRange(vin, index + 1, vin.length)
                     );

        return root;
    }

    public int findRootIndexInOrder(int[] pre, int[] vin) {
        for (int i = 0; i < vin.length; i++) {
            if (pre[0] == vin[i]) return i;
        }
        return 0;
    }
经验分享 程序员 微信小程序 职场和发展