一起学习LeetCode热题100道(47/100)

47.从前序与中序遍历序列构造二叉树(学习)

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

示例 1:
在这里插入图片描述
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]

示例 2:
输入: preorder = [-1], inorder = [-1]
输出: [-1]

提示:
1 <= preorder.length <= 3000
inorder.length == preorder.length
-3000 <= preorder[i], inorder[i] <= 3000
preorder 和 inorder 均 无重复 元素
inorder 均出现在 preorder
preorder 保证 为二叉树的前序遍历序列
inorder 保证 为二叉树的中序遍历序列

解析:
一、找到根节点:
先序遍历的第一个元素是 3,所以根节点是 3。

二、分割中序遍历数组:
1.在中序遍历数组 [9, 3, 15, 20, 7] 中找到 3 的索引,为 1。
2.因此,左子树的中序遍历是 [9],右子树的中序遍历是 [15, 20, 7]。

三、确定子数组的长度:
1.左子树中序遍历的长度是 1,所以左子树先序遍历的长度也是 1(从第二个元素开始,即 9)。
2.右子树的中序遍历长度是 3,所以右子树先序遍历是从 20 开始的 3 个元素([20, 15, 7])。

四、递归构建子树:
1.使用 [9] 和 [9] 构建左子树(注意这里左子树先序遍历和中序遍历都只有一个元素,且相同)。
2.使用 [15, 20, 7] 和 [20, 15, 7] 构建右子树(递归过程相同,但规模更小)。

五、返回根节点:
最终返回构建好的根节点 3,其左子节点是 9,右子树是一个包含 20 为根节点的子树。

var buildTree = function (preorder, inorder) {
    if (preorder.length === 0 || inorder.length === 0) {
        return null;
    }

    // 先序遍历的第一个元素是根节点  
    const rootVal = preorder[0];
    let root = new TreeNode(rootVal);

    // 在中序遍历中找到根节点的位置  
    let inorderRootIndex = inorder.indexOf(rootVal);

    // 切割中序遍历数组,得到左子树和右子树的中序遍历  
    const inorderLeft = inorder.slice(0, inorderRootIndex);
    const inorderRight = inorder.slice(inorderRootIndex + 1);

    // 根据中序遍历的切割,切割先序遍历数组  
    // 注意,左子树的先序遍历长度应该和中序遍历长度一致  
    const preorderLeft = preorder.slice(1, 1 + inorderLeft.length);
    const preorderRight = preorder.slice(1 + inorderLeft.length);

    // 递归构建左子树和右子树  
    root.left = buildTree(preorderLeft, inorderLeft);
    root.right = buildTree(preorderRight, inorderRight);

    return root;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值