附上牛客网练习题连接,传送门
题目描述
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
解题方法
思路就是利用递归,二叉树的前序遍历和中序遍历中确定根节点位置,假设有n个节点,在中序遍历左侧的值是左子树的节点,假设共有m个,右侧的值是右子树的节点,则右子树节点为n-m-1个;在前序遍历中,根节点紧挨着的m个节点就是左子树节点,剩下n-m-1个节点就是右子树节点。这样递归就可以分别计算出各自的左子树和右子树。
function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
}
function reConstructBinaryTree(pre, vin)
{
// write code here
/* 方法1 利用数组的slice方法 */
if(vin.length === 0){
return null;
}
let root = 0,
head = new TreeNode(pre[0]),
preLeft = [],
preRight = [],
inLeft = [],
inRight = [];
//寻找中序遍历中根节点的位置
while(vin[root] !== pre[0] ){
root += 1;
}
if(root!==0){
//slice函数包括start位置的元素但是不包括end位置的元素
inLeft = vin.slice(0,root);
preLeft = pre.slice(1,root+1);
}
if(root!==vin.length-1){
inRight = vin.slice(root+1);
preRight = pre.slice(root+1);
}
head.left = reConstructBinaryTree(preLeft,inLeft);
head.right = reConstructBinaryTree(preRight,inRight);
return head;
/* 方法二 直接循环赋值 */
if(vin.length === 0)
return null;
let root = 0,
i,
preLeft = [],
preRight = [],
inLeft = [],
inRight = [];
let head = new TreeNode(pre[0]);
while(vin[root] !== pre[0] ){
root += 1;
}
for(i = 0; i < root; i++){
preLeft.push(pre[i+1]);
inLeft.push(vin[i]);
}
for(i = root + 1; i < vin.length; i++){
preRight.push(pre[i]);
inRight.push(vin[i]);
}
head.left = reConstructBinaryTree(preLeft, inLeft);
head.right = reConstructBinaryTree(preRight, inRight);
return head;
}
只要注释,就可以跑了。