先贴代码 TreeNode类定义 class TreeNode{ public int val; public TreeNode left; public TreeNode right; public TreeNode(int val){ this.val=val; } }
//不得不吐槽一下:以int[]作为参数大大增加了老夫的代码量
public static TreeNode reConstructBinaryTree(int[] pre, int[] in){ int fatherData= pre[0]; List<Integer> preList=new ArrayList<>(); List<Integer> inList=new ArrayList<>(); for(int i=0;i<pre.length;i++){ preList.add(pre[i]); inList.add(in[i]); } int index= inList.indexOf(fatherData); TreeNode father=new TreeNode(fatherData); List<Integer> lInorder= inList.subList(0,index); List<Integer> rInorder= inList.subList(index+1, inList.size()); List<Integer> rPreorder= preList.subList(index+1, preList.size()); List<Integer> lPreorder= preList.subList(1,index+1); if(lInorder.size()!=0){ father.left=reConstructBinaryTree(lPreorder.stream().mapToInt(Integer::intValue).toArray(),lInorder.stream().mapToInt(Integer::intValue).toArray()); } if(rInorder.size()!=0){ father.right=reConstructBinaryTree(rPreorder.stream().mapToInt(Integer::intValue).toArray(),rInorder.stream().mapToInt(Integer::intValue).toArray()); } return father; }
================================================================================================
思路:
以题目给出的序列为例:
前序:{1,2,4,7,3,5,6,8} 中序:{4,7,2,1,5,3,8,6}
本题目主要是根据回溯的思想解题:
由前序遍历的特点可知:
节点1作为前序遍历的第一个节点,必然是根节点
由中序遍历的特点可知:
节点1左边的{4,7,2}节点必然是在节点1的左子树上,{5,3,8,6}在其右子树上
接下来,在中序序列中根据1的位置进行左右切割,可以得出其左右子树的前序序列和中序列。
同理,对于前序{2,4,7}中序{4,7,2}的子树来说,节点2是根节点,{4,7}节点依据在中序序列中的位置:
{4,7}在节点2的左子树上
依着这个思路递归下去,在每一个被切割出来的子序列中,选定其所代表的子树的根节点,然后使用上一级根节点的左/右指针指向新的根节点,就可以重新构建出原来的二叉树。