题目:
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:3
/ \
9 20
/ \
15 7
思路:
画个图对比一下会更容易理解
1. 前序遍历的第一个元素就是 root 节点对应的值
2. 根据前序遍历判断出 root 的值,在对应的中序遍历中可以找到 root 节点所在的位置 index
则 index 之前的元素是左子树,index 之后的是右子树,从而得到左子树的长度 leftSize = index - inStart
3. 根据 2 可以得出前序遍历中,左子树的范围是从 [preStart + 1, preStart + leftSize],
右子树是[preStart + leftSize + 1, preEnd]
代码实现:
/**
* 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) {
return build(preorder, 0, preorder.length - 1,
inorder, 0, inorder.length - 1);
};
var build = function (preorder, preStart, preEnd, inorder, inStart, inEnd) {
if (preStart > preEnd) {
return null;
}
// root 节点对应的值就是前序遍历数组的第一个元素
let rootVal = preorder[preStart];
// rootVal 在中序遍历数组中的索引
let index = inorder.findIndex(item => item === rootVal);
let leftSize = index - inStart;
// 先构造出当前根节点
let root = new TreeNode(rootVal);
// 递归构造左右子树
root.left = build(preorder, preStart + 1, preStart + leftSize,
inorder, inStart, index - 1);
root.right = build(preorder, preStart + leftSize + 1, preEnd,
inorder, index + 1, inEnd);
return root;
}