每日一题--从前序与中序遍历序列构造二叉树

493 阅读1分钟

「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战」。

题目 给定一棵树的前序遍历 preorder 与中序遍历  inorder。请构造二叉树并返回其根节点。

 

示例 1:

Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]

Output: [3,9,20,null,null,15,7]

示例 2:

Input: preorder = [-1], inorder = [-1]

Output: [-1]  

提示:

1 <= preorder.length <= 3000

inorder.length == preorder.length

-3000 <= preorder[i], inorder[i] <= 3000

preorder 和 inorder 均无重复元素

inorder 均出现在 preorder

preorder 保证为二叉树的前序遍历序列

inorder 保证为二叉树的中序遍历序列

思路

先序遍历的顺序是根节点,左子树,右子树。中序遍历的顺序是左子树,根节点,右子树。

所以我们只需要根据先序遍历得到根节点,然后在中序遍历中找到根节点的位置,它的左边就是左子树的节点,右边就是右子树的节点。

生成左子树和右子树就可以递归的进行了。

我们来分析一下。

preorder = [3,9,20,15,7] inorder = [9,3,15,20,7] 首先根据 preorder 找到根节点是 3

然后根据根节点将 inorder 分成左子树和右子树 左子树 inorder [9]

右子树 inorder [15,20,7]

把相应的前序遍历的数组也加进来 左子树 preorder[9] inorder [9]

右子树 preorder[20 15 7] inorder [15,20,7]

现在我们只需要构造左子树和右子树即可,成功把大问题化成了小问题 然后重复上边的步骤继续划分,直到 preorder 和 inorder 都为空,返回 null 即可

代码

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {number[]} preorder
 * @param {number[]} inorder
 * @return {TreeNode}
 */
var buildTree = function(preorder, inorder) {
    if(!preorder.length)
        return null;
    let root = new TreeNode(preorder[0]);
    let mid = inorder.findIndex((number) => number === root.val);
    root.left = buildTree(preorder.slice(1, mid + 1), inorder.slice(0, mid));
    root.right = buildTree(preorder.slice(mid + 1, preorder.length), inorder.slice(mid + 1, inorder.length));
    return root;
};