给定一棵树的前序遍历 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]
首先我们要了解什么是前序遍历,什么是中序遍历。
前序遍历是所有结点都按照[中,左,右]的顺序排列。
中序遍历是指所有的结点都按照[左,中,右]的顺序排列。
知道了这些我们就知道,任何前序遍历的第一个元素都是该树的根节点。而我们确定了根节点之后,我们从中序遍历中找到根节点,其左边的便都是其左子节点。右边的是其右子结点。再根据左右子节点的前序遍历的第一个元素便能确定其子结点的值,依次递归。便能确定整棵树。
var buildTree = function (preorder, inorder) {
// 终止条件
if (preorder.length == 0) return null;
// 计数查找根节点在中序遍历中的位置。
let pos = 0;
while (inorder[pos] != preorder[0]) pos++;
// 记录左右子树的前中序遍历的值。
let l_pre = [], l_in = [], r_pre = [], r_in = [];
// 对左子树的前中序遍历进行赋值。
for (let i = 0; i < pos; i++) {
l_pre.push(preorder[i + 1]);
l_in.push(inorder[i])
}
// 对右子树的前中序遍历进行赋值。
for (let i = pos + 1; i < preorder.length; i++) {
r_in.push(inorder[i]);
r_pre.push(preorder[i])
}
// 生成并返回该树
let node = new TreeNode(preorder[0], buildTree(l_pre, l_in), buildTree(r_pre, r_in))
return node
};