1.题目:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
2.思路:
根据中序遍历和前序遍历可以确定二叉树,具体过程为:

根据前序序列第一个结点确定根结点
根据根结点在中序序列中的位置分割出左右两个子序列
对左子树和右子树分别递归使用同样的方法继续分解 

例如:
前序序列{1,2,4,7,3,5,6,8} = pre
中序序列{4,7,2,1,5,3,8,6} = in

根据当前前序序列的第一个结点确定根结点,为 1
找到 1 在中序遍历序列中的位置,为 in[3]
切割左右子树,则 in[3] 前面的为左子树, in[3] 后面的为右子树
则切割后的左子树前序序列为:{2,4,7},切割后的左子树中序序列为:{4,7,2};切割后的右子树前序序列为:{3,5,6,8},切割后的右子树中序序列为:{5,3,8,6}
对子树分别使用同样的方法分解 

方法一:使用类库复制数组,不大好

import java.util.Arrays;
public class Solution {
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        if(pre.length==0||in.length==0){//判空
            return null;
        }
        TreeNode node=new TreeNode(pre[0]);//找到根节点,一定在前序遍历的第一个
        for(int i=0;i<in.length;i++){//遍历
            if(pre[0]==in[i]){//找到中序遍历中的根节点位置,拆分为两部分
                node.left=reConstructBinaryTree(Arrays.copyOfRange(pre,1,i+1),Arrays.copyOfRange(in,0,i));//递归左子树
                node.right=reConstructBinaryTree(Arrays.copyOfRange(pre,i+1,pre.length),Arrays.copyOfRange(in,i+1,in.length));//递归右子树
                break;//找到则跳出
            }
        }
        return node;//返回
    }
}

方法二:也是使用分治算法,利用递归进行重建

图片说明
推算:
图片说明

import java.util.*;
public class Solution {
    HashMap<Integer,Integer> dic=new HashMap<>();
    int[] pre;
    public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
        if(pre.length!=in.length) return null;//前序遍历长度与中序遍历长度一定向等
        for(int i=0;i<in.length;i++){//先将中序遍历存入map中,这样以后就不用再遍历了
            dic.put(in[i],i);
        }
        this.pre=pre;

        return rebuildTree(0,0,pre.length-1);
    }
    private TreeNode rebuildTree(int root,int inLeft,int inRight){
        if(inLeft>inRight) return null;
        TreeNode node=new TreeNode(pre[root]);//构建头节点
        int index=dic.get(node.val);//通过map找到在中序遍历中的未知,进行左右子树的拆分
        node.left=rebuildTree(root+1,inLeft,index-1);
        node.right=rebuildTree(index-inLeft+root+1,index+1,inRight);
        return node;
    }
}