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;
}
}
京公网安备 11010502036488号