从前序与中序遍历序列构造二叉树
Posted: 09.28.2019
描述

算法
- 核心思想一共有两点:
- 对于前序遍历来说,当前数组的第一个元素便是这棵树的根节点,剩下的则是左侧子树与右侧子树(分别形成一个组)
- 这个时候我们拿到了根节点,而这个根节点对于中序遍历来说,也是适用的
- 对于中序遍历来说,根节点左侧的部分便是左侧子树,根节点右侧的部分便是右侧子树
- 对于前序遍历来说,当前数组的第一个元素便是这棵树的根节点,剩下的则是左侧子树与右侧子树(分别形成一个组)
- 因此,在每次递归的时候
- 从前序遍历的数组中,选择第一个元素,该元素便是当前子树的根节点
- 在中序遍历的数组中,找到根节点所在的位置
- 该位置左侧便是 inorderLeft,右侧便是 inorderRight(下一层递归的俩中序遍历数组)
- 然后再回到前序遍历的数组,根据 inorderLeft 的长度,可以确定 preorderLeft 的长度(这俩长度一样)
- 然后再根据长度进行 slice,得到 preorderLeft 和 preorderRight
- 最后再分别将左侧子树与右侧子树利用递归实现
代码
/**
* 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) {
// edge case
if (!preorder.length || !inorder.length) return null;
return constructTree(preorder, inorder);
};
function constructTree(preorder, inorder) {
if (!preorder.length) return null;
// 在中序遍历的数组中找到 rootIndex,然后分割
const node = new TreeNode(preorder[0]);
const rootIndex = inorder.indexOf(preorder[0]);
const inorderLeft = inorder.slice(0, rootIndex);
const inorderRight = inorder.slice(rootIndex + 1);
// 递归
node.left = constructTree(preorder.slice(1, 1 + inorderLeft.length), inorderLeft);
node.right = constructTree(preorder.slice(1 + inorderLeft.length), inorderRight);
return node;
}