BM40 重建二叉树

1.题目描述

给定节点数为 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≤2000n≤2000,节点的值 −10000≤val≤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}

2.解题思路

如何通过中序和前序序列唯一的确定一棵二叉树:

1.前序序列的首个结点就是根节点;

2.根据根节点的值到中序序列中寻找出现的位置idx;

3.切分中序序列[0:idx]即为左子树的中序序列,[idx+1:vinOrder.length]即为右子树的中序序列

4.由于每个子树的前序序列和中序序列具有相同的长度,那么根据4得出的左右子树的中序序列,可以分别得到左右子树的前序序列

6.分别由左右子树的前序和中序序列递归的重建左右子树,最终返回root即可

3.代码实现

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 *   public TreeNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param preOrder int整型一维数组
     * @param vinOrder int整型一维数组
     * @return TreeNode类
     */
    public TreeNode reConstructBinaryTree (int[] preOrder, int[] vinOrder) {
        // write code here
        int n = preOrder.length;
        if (n == 0) {
            return null;
        }
        TreeNode root = new TreeNode(preOrder[0]);
        int idx = 0;
        //找根节点在中序序列中的下标idx
        for (int i = 0; i < vinOrder.length; i++) {
            if (vinOrder[i] == preOrder[0]) {
                idx = i;
                break;
            }
        }
        //根据下标idx切分中序
        int[] leftVin = Arrays.copyOfRange(vinOrder, 0, idx);
        int[] leftPre = Arrays.copyOfRange(preOrder, 1, 1 + leftVin.length);
        root.left = reConstructBinaryTree(leftPre, leftVin);

        int[] rightVin = Arrays.copyOfRange(vinOrder, idx + 1, vinOrder.length);
        int[] rightPre = Arrays.copyOfRange(preOrder, 1 + leftPre.length,
                                            1 + leftPre.length + rightVin.length);
        root.right = reConstructBinaryTree(rightPre, rightVin);

        return root;

    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值