先序中序建立一棵二叉树
https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
根据一棵树的前序遍历与中序遍历构造二叉树。
Version1
public class BuildTree {
public TreeNode buildTree(int[] pre, int[] in) {
//头结点为空,或者两者长度不等,都返回null。
if(pre==null||in==null||pre.length!=in.length){
return null;
}
return buildBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
}
//pre:[L1....R1] in:[L2....R2]
public TreeNode buildBinaryTree(int[] pre, int L1,int R1,int[] in,int L2,int R2){
//如果L1>R1,表示没有左节点,建不成树,所以返回null。(比如:先序和中序都是1,2,3
if(L1>R1){
return null;
}
//建立头结点,供返回
TreeNode head=new TreeNode(pre[L1]);
//L1==R1:表示,只有一个节点
if(L1==R1){
return head;
}
//find:表示头结点在中序中的下标。
int find=L2;
while (in[find]!=pre[L1]){
find++;
}
//下边的边界如果难确定,就通过具体数字,进行判断,否则,出错了,很难找。
head.left=buildBinaryTree(pre,L1+1,L1+find-L2,in,L2,find-1);
head.right=buildBinaryTree(pre,L1+find-L2+1,R1,in,find+1,R2);
return head;
}
}
Version2
改进:将中序数组的<下标值,下标>存储到哈希表HashMap中,这样就不用每次查找了。
public class BuildTree2 {
public TreeNode buildTree(int[] pre, int[] in) {
if(pre==null||in==null||pre.length!=in.length){
return null;
}
//创建哈希表,存储中序数组的<下标值,下标>
HashMap<Integer,Integer> hashMap=new HashMap<>();
for(int i=0;i<in.length;i++){
hashMap.put(in[i],i);
}
//将哈希表传到函数中,供buildBinaryTree调用
return buildBinaryTree(pre,0,pre.length-1,in,0,in.length-1,hashMap);
}
public TreeNode buildBinaryTree(int[] pre, int L1, int R1, int[] in, int L2, int R2, HashMap<Integer,Integer> hashMap){
if(L1>R1){
return null;
}
TreeNode head=new TreeNode(pre[L1]);
if(L1==R1){
return head;
}
int find=hashMap.get(pre[L1]);
head.left=buildBinaryTree(pre,L1+1,L1+find-L2,in,L2,find-1,hashMap);
head.right=buildBinaryTree(pre,L1+find-L2+1,R1,in,find+1,R2,hashMap);
return head;
}
}