【题目描述】输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
【解题思路1】
//1. 先序遍历中,第一个结点即根节点。根据根节点,可以将中序遍历序列分为两部分,左边的即左子树,右边的即右子树。
//2. 根据其对应关系,在先序遍历序列中,找的根节点的左子树和右子树。
//3. 这样,就获得了左子树的先序遍历序列和中序遍历序列,也获得了右子树的先序遍历序列和中序遍历序列。
//4. 递归处理每个节点,返回根节点。
//实现一
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
int len = pre.length;
if(len == 0){
return null;
}else{
TreeNode tNode = new TreeNode(pre[0]);
int loc = getIndex(pre[0], in);
int[] preTempL = getSubArray(1, loc, pre); //获取左子树的先序遍历序列
int[] inTempL = getSubArray(0, loc-1, in); //获取左子树的中序遍历序列
int[] preTempR = getSubArray(loc+1, len-1, pre); //获取右子树的先序遍历序列
int[] inTempR = getSubArray(loc+1, len-1, in); //获取右子树的中序遍历序列
tNode.left = reConstructBinaryTree(preTempL, inTempL); //递归构建当前节点的左子树
tNode.right = reConstructBinaryTree(preTempR, inTempR); //递归构建当前节点的右子树
return tNode;
}
}
//根据起始坐标获取数组中的指定子串
public int[] getSubArray(int inx, int end, int[] arr){
int[] subArr = new int[end-inx+1];
for(int i=inx;i<=end; i++){
subArr[i-inx] = arr[i];
}
return subArr;
}
//获取元素在数组中的下标位置
public int getIndex(int target, int[] arr){
int i=0;
for(int a: arr){
if(a == target){
break;
}
i++;
}
return i;
}
}
//实现二
链接:https://www.nowcoder.com/questionTerminal/8a19cbe657394eeaac2f6ea9b0f6fcf6
来源:牛客网
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
TreeNode root=reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
return root;
}
//前序遍历{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
private TreeNode reConstructBinaryTree(int [] pre,int startPre,int endPre,int [] in,int startIn,int endIn) {
if(startPre>endPre||startIn>endIn)
return null;
TreeNode root=new TreeNode(pre[startPre]);
for(int i=startIn;i<=endIn;i++)
if(in[i]==pre[startPre]){
root.left=reConstructBinaryTree(pre,startPre+1,startPre+i-startIn,in,startIn,i-1);
root.right=reConstructBinaryTree(pre,i-startIn+startPre+1,endPre,in,i+1,endIn);
}
return root;
}
}