该文对剑指Offer的第四题根据二叉树的先序和中序遍历构造二叉树
题目描述:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
示例
输入:
前序遍历:[1,2,3,4,5,6,7]
中序遍历:[3,2,4,1,6,5,7]
输出:
二叉树:{1,2,5,3,4,6,7}
想要做出该题,首先应该知道二叉树的前、中、后遍历。(下面简单说下三个遍历)
前:先输出根节点,在输出左孩子,然后输出右孩子(遍历序列的第一个数就是整个树的根节点)
中:先输出左孩子,在输出根节点,最后输出右孩子(根节点在左右子树之间,可根据前序和后序中已知的根节点进行划分子树)
后:先输出左孩子,在输出右孩子,然后输出根节点(遍历序列的倒数第一个数就是整个树的根节点)
好了,基本知识了解了,下一步做题吧
该题解法是模拟人工重构二叉树的方式进行求解
为了方便讲解,本人已将示例中的二叉树画出,如下图(很丑)
我们都知道前序遍历第一个数就是整个树的根节点,根据根节点可以将整个树分为左子树和右子树,即可根据根节点的值从中序遍历的序列中找出左右子树的中序遍历的序列,依次类推,即可重新构建。
看完上面的分析,大多数人可以想到递归遍历算法,通过划分左右子树的方式递归,直到空集。但是怎么写代码呢?
下面给出两种递归求解方法:
方法1:值传递递归(通过复制左右子树的值进行求解)
public TreeNode reConstructBinaryTree1(int [] pre,int [] in) {
if(pre == null || in == null || pre.length == 0 || in.length == 0) {
return null;
}
if(pre.length != in.length) {
return null;
}
TreeNode root = new TreeNode(pre[0]);//根节点
for(int i = 0; i < pre.length; i