47-leetCode: 105. 从前序与中序遍历序列构造二叉树

89 阅读2分钟

题目

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

 

示例

输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]

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

解题思路

本题采用递归的思想,首先判断特殊情况,如果传入数组均为空,则直接返回null;然后找到根节点:根据前序遍历的特点,跟节点就是数组的第一个节点,同时创建二叉树跟节点,再找到根节点在前序遍历的位置:index;再据中序遍历的特点,根节点前面的节点是根节点的左节点二叉树的中序遍历,根节点后面的节点就是根节点右节点二叉树的中序遍历。最后返回该根节点

/**
 * @param {number[]} preorder
 * @param {number[]} inorder
 * @return {TreeNode}
 */
var buildTree = function(preorder, inorder) {
    // 当当前遍历数组均为空时,说明遍历到了空节点,直接返回null
    if (!preorder.length || !inorder.length) return null;

    // 找到根节点的位置:因为前序遍历的第一个元素就是根节点
    let node = new TreeNode(preorder[0]);

    // 找到根节点在中序遍历的位置, 利用数组的shift方法可以将根节点从preorder数组中取出,同时返回根节点。
    let index = inorder.indexOf(preorder.shift());

    // 除去两个遍历数组的根节点后,假设buildTree方法已经为我们找到了根节点的左右节点,即:递归。
    // 其中左节点的前序遍历应该是preorder:之前已经将根节点移出,中序遍历应该是第一位到index的值
    // 其中右节点的前序遍历与左节点前序遍历一致,中序遍历移出的节点应该是index之后的值
    node.left = buildTree(preorder, inorder.slice(0, index));
    node.right = buildTree(preorder, inorder.slice(index + 1));

    return node;
};