105. 从前序与中序遍历序列构造二叉树

2022-08-19 14:45:29 浏览数 (1)

105. 从前序与中序遍历序列构造二叉树

力扣题目链接[1]

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

示例1:

代码语言:javascript复制
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
输出: [3,9,20,null,null,15,7]

提示:

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

思路:

本题考查前序和中序遍历的特点。

  • 前序遍历:根左右
  • 中序遍历:左根右

我们通过前序遍历可以找到二叉树的根。根据中序遍历,我们可以知道根的左右子树的中序遍历及左右子树节点数目。知道左右子树的节点数目,结合前序遍历,我们就知道左右子树的前序遍历。

然后结合左右子树的前序和中序遍历,递归的构造左右子树为当前构造出节点的左右子树。

代码语言:javascript复制
/**
 * 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; // 二叉树为空
    const root = preorder[0]; // 从前序遍历获取根节点
    const node = new TreeNode(root); // 通过根节点构造节点
    const index = inorder.indexOf(root); // 从中序遍历获取根节点的索引
    const inLeft = inorder.slice(0, index); // 中序遍历的左子树
    const inRight = inorder.slice(index   1); // 中序遍历的右子树
    const preLeft = preorder.slice(1, index   1); // 前序遍历的左子树
    const preRight = preorder.slice(index   1); // 前序遍历的右子树
    node.left = buildTree(preLeft, inLeft); // 递归构造左子树
    node.right = buildTree(preRight, inRight); // 递归构造右子树
    return node; // 返回构造出的节点
};

总结

本题需要结合前序遍历和中序遍历,来将二叉树拆分为左子树、根、右子树三个部分。找出根节点就调用构造函数构造出新节点,左右子树分别有前序遍历和中序遍历两个顺序,然后递归调用函数进而找到左子树的根节点,以及右子树的根节点。这两个根节点恰好就是刚才构造出的新节点的左右子节点,这样便可以递归的构造出一个完整的二叉树。

最终返回根节点即可。

参考资料

[1]

力扣题目链接: https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/

0 人点赞