ps 重新开启每日刷题了
题目描述:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
题目分析:
这其实是一个我们非常熟悉的二叉树问题,根据先中,或后中重建二叉树。手写时它的思路是这样的:先序判根中序判左右。(这里就不会手写的了,毕竟它在数据结构中也是蛮简单的题型)
举例:题目中先看先序,1肯定是它的根节点、接下来找左右。看中序中1的位置,1左边即左节点元素、右边即右节点元素。那么接下来肯定是得找根节点1的左子树根节点,还是先看先序,即2是左子树根节点。那么这个左子树的左右子树呢?还是看中序,2的左有4、7,右没有了。即节点2仅有右子树,然后继续这样找下去。。。
思路很容易看出来,还是递归。(好像一般树的操作基本都是递归)
我们主要的操作就是不断的找出子树的先序和中序队列。
代码实现
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
function reConstructBinaryTree(pre, vin) {
if (pre.length == 0 || vin.length == 0) {
return null;
};
if (pre.length != vin.length) {
return null;
}
//先序判根中序判左右
let index = vin.indexOf(pre[0]);
let left = vin.slice(0, index); //中序左子树
let right = vin.slice(index + 1); //中序右子树
let preLeft = pre.slice(1, index + 1); //先序左子树
let preRight = pre.slice(index + 1); //先序右子树
return {
val: pre[0],
//左边找
left: reConstructBinaryTree(preLeft, left),
//右边找
right: reConstructBinaryTree(preRight, right)
};
}