题目链接:

题目描述:

根据二叉树的前序遍历和中序遍历的结果,重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

image.png

题目思路:

前序遍历的第一个值为根节点的值,使用这个值将中序遍历结果分成两部分,左部分为树的左子树中序遍历结果,右部分为树的右子树中序遍历的结果。然后分别对左右子树递归地求解。

5d2e29b4-078b-4202-ae4d-44cd8a2b69df.jpg

代码:

  1. package com.newcoder;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. /**
  5. * @author : weigang
  6. * @date : 2021/3/12 - 16:40
  7. * 重建二叉树
  8. **/
  9. class TreeNode {
  10. int val;
  11. TreeNode left;
  12. TreeNode right;
  13. TreeNode(int x) { val = x; }
  14. }
  15. public class no4 {
  16. public TreeNode reConstructBinaryTree(int [] pre,int [] in) {
  17. TreeNode root=reConstructBinaryTree(pre,0,pre.length-1,in,0,in.length-1);
  18. return root;
  19. }
  20. //前序遍历{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6}
  21. private TreeNode reConstructBinaryTree(int [] pre,int startPre,int endPre,int [] in,int startIn,int endIn) {
  22. if(startPre>endPre||startIn>endIn){
  23. return null;
  24. }
  25. TreeNode root=new TreeNode(pre[startPre]);
  26. for(int i=startIn;i<=endIn;i++){
  27. if(in[i]==pre[startPre]){
  28. root.left=reConstructBinaryTree(pre,startPre+1,startPre+i-startIn,in,startIn,i-1);
  29. root.right=reConstructBinaryTree(pre,startPre+i-startIn+1,endPre,in,i+1,endIn);
  30. break;
  31. }
  32. }
  33. return root;
  34. }
  35. public static void main(String[] args) {
  36. int[] pre = {1,2,3,4,5,6,7};
  37. int [] in = {3,2,4,1,6,5,7};
  38. System.out.println(new no4().reConstructBinaryTree(pre,in));
  39. }
  40. }

代码分析:

前序遍历的第一个数是根节点,通过找到根节点在中序遍历的索引,就可以判断出根节点的左子树有多少个,继而就可以在前序遍历和中序遍历中拆分出根节点的左子树和右子树。通过代码可知,根节点的左子树有i-startIn 个节点。所以

左子树

  • 在前序遍历中的起始和末尾索引是startPre+1,startPre+i-startIn,
  • 在中序遍历中的起始和末尾索引是startIn,i-1

右子树

  • 在前序遍历中的起始和末尾索引是i-startIn+startPre+1,endPre
  • 在中序遍历中的起始和末尾索引是i+1,endIn