题目:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
1、分析原理:
根据前序和中序的特性,前序序列的一个元素就是树的根元素,那么在中序序列找到相应的元素。找到后该元素前面所有元素都是左子树元素,后面元素都是右子树元素。那么此时跟节点的pleft就是左子树返回的结果,pright就是右子树返回的结果,使之递归即可,递归出口就是前序区间只有一个元素时。
2、思路一:前序和中序必须结合搭配
使用递归,每次分清根结点、左子树、右子树,递归进行构建。
先序遍历第一个位置肯定是根节点node,中序遍历的根节点位置在中间p,在p左边的肯定是node的左子树的中序数组,p右边的肯定是node的右子树的中序数组。
重构函数(前序数组,前序数组头,前序数组尾,中序数组,中序数组头,中序数组尾);
根据前序数组的第一个值遍历中序数组,找到之后即可分清前序和中序数组中左子树和右子树的组成部分,得到四个新的数组。
新左子树:前序部分、中序部分
新右子树:前序部分、中序部分
注意:数组的边界
找到左右子树之后,当成新的前序中序数组传入重构函数进进一步构建,递归!
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left; //左子树
* TreeNode right; //右子树
* TreeNode(int x) { val = x; }
* }
*/
public class Solution {
public TreeNode reConstructBinaryTree(int [] pre,int [] in) { //输入前序中序数组
return reConBTree(pre,0,pre.length-1,in,0,in.length-1);
}
//使用递归不断寻找根节点、左子树、右子树
//每次都输入新的树的前序和后序数组
public TreeNode reConBTree(int[] pre, int preleft, int preright, int[] in, int inleft, int inright){
if(preleft > preright || inleft > inright){ //数组遍历完毕
return null;
}
//新建一个TreeBTree
TreeNode root = new TreeNode(pre[preleft]);
//遍历中序数组,找到根节点,和左右子树
for(int i=0; i < in.length; i++){
if(in[i] == pre[preleft]){
//重构左子树,使用递归
root.left = reConBTree(pre, preleft+1, preleft+i-inleft, in, inleft, i-1);
//重构右子树,使用递归
root.right = reConBTree(pre, preleft+i-inleft+1, preright, in, i+1, inright);
}
}
return root;
}
}