写点什么

LeetCode 题解:105. 从前序与中序遍历序列构造二叉树,递归 + 数组切割,JavaScript,详细注释

用户头像
Lee Chen
关注
发布于: 2021 年 01 月 13 日
LeetCode题解:105. 从前序与中序遍历序列构造二叉树,递归+数组切割,JavaScript,详细注释

原题连接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/


解题思路:


  1. 参考了多种解法,逐渐优化(补充国外大佬解法)和[动画演示 105. 从前序与中序遍历序列构造二叉树](https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/solution/dong-hua-yan-shi-105-cong-qian-xu-yu-zhong-xu-bian/)。

  2. 假设有一个二叉树如下:


	      1	    /   \	   2     3	  / \   / \ 	 4   5 6   7
复制代码


前序遍历的结果是: [1,2,4,5,3,6,7]

中序遍历的结果是: [4,2,5,1,6,3,7]


  1. 可以将其从根节点 1,拆分成两个子树,如下:


左子树:


	   2	  / \	 4   5
复制代码


前序遍历的结果是: [2,4,5]

中序遍历的结果是: [4,2,5]


右子树:


	   3	  / \ 	 6   7
复制代码


前序遍历的结果是: [3,6,7]

中序遍历的结果是: [6,3,7]


  1. 我们可以按照步骤 3,将左右子树继续按照根节点继续拆分,可以总结出如下规律:


* 二叉树的根节点始终在preorder[0]

* 二叉树可以按照根节点在inorder中的位置rootIndex,将preorderinorder拆分成左右两个子树的结果,如下:


左子树遍历结果:

```

preorder = preorder.slice(1, rootIndex + 1);

inorder = inorder.slice(0, rootIndex);

```


右子树遍历结果:

```

preorder = preorder.slice(rootIndex + 1);

inorder = inorder.slice(rootIndex + 1);

```


  1. 经过步骤 4 的分析,我们可以按照以下逻辑进行递归:


* 每次递归用preorder[0]的值生成一个根节点。

* 在通过preorder[0]找到其在inorder中的位置rootIndex,将preorderinorder切割成两部分,分别进行下一层的递归。

* 将下层递归生成的左右子树,连接到当前根节点上。

* 递归完成时将当前根节点返回,供上一层递归连接。

* preorderinorder中的所有值都生成过节点之后,也就完成了整个二叉树的生成。


/** * Definition for a binary tree node. * function TreeNode(val) { *     this.val = val; *     this.left = this.right = null; * } *//** * @param {number[]} preorder * @param {number[]} inorder * @return {TreeNode} */var buildTree = function (preorder, inorder) {  // 递归切割数组到最后,数组会为空,此时退出循环  if (preorder.length === 0) {    // 数组为空时,表示当前已经无节点需要生成,返回null    // 让上一层节点的left和right指针指向null    return null;  }
// 使用当前值创建一个节点,即为一个树的根节点 const root = new TreeNode(preorder[0]); // 查找到当前根节点在数组中的位置 const rootIndex = inorder.findIndex((value) => preorder[0] === value);
// 将数组对应左子树的部分切割,向下递归 // 将当前根节点与已生成好的左子树连接 root.left = buildTree( preorder.slice(1, rootIndex + 1), inorder.slice(0, rootIndex), ); // 将数组对应右子树的部分切割,向下递归 // 将当前根节点与已生成好的右子树连接 root.right = buildTree( preorder.slice(rootIndex + 1), inorder.slice(rootIndex + 1), );
// 将根节点返回供上层节点连接 return root;};
复制代码


发布于: 2021 年 01 月 13 日阅读数: 13
用户头像

Lee Chen

关注

还未添加个人签名 2018.08.29 加入

还未添加个人简介

评论

发布
暂无评论
LeetCode题解:105. 从前序与中序遍历序列构造二叉树,递归+数组切割,JavaScript,详细注释