1. package treeAndRecursion.code105;
    2. import treeAndRecursion.TreeNode;
    3. public class Solution {
    4. int[] preorder;
    5. int[] inorder;
    6. public TreeNode buildTree(int[] preorder, int[] inorder) {
    7. //作为类成员变量,省着传了
    8. this.preorder = preorder;
    9. this.inorder = inorder;
    10. //让全部整段去构建
    11. return bulid(0, preorder.length-1,0,inorder.length-1);
    12. }
    13. /**
    14. * 用先序遍历的一段 和 中序遍历的一段 去还原当前这一部分树(子树)
    15. * @param preLeft 先序遍历的左起始点
    16. * @param preRight 先序遍历的右结束点
    17. * @param inLeft 中序遍历的左起始点
    18. * @param inRight 中序遍历的右结束点
    19. * @return
    20. */
    21. public TreeNode bulid(int preLeft,int preRight,int inLeft,int inRight){
    22. //递归结束条件,当left > right
    23. if(preLeft > preRight){
    24. return null;
    25. }
    26. // 1 : 先序遍历是 根 左 右,所以先序遍历第一个值 preLeft 就是根
    27. TreeNode root = new TreeNode(preorder[preLeft]);
    28. // 2 : 确立了根之后。去找左右子树。
    29. // 2.1:因为中序遍历是 左 根 右,所以在中序遍历中找到根 mid 就是中序遍历中根的下标
    30. // 2.2:根左边就是左子树 inLeft ~ (mid -1)
    31. // 2.3:根右边就是右子树 (mid + 1) ~ inRight
    32. // 从inLeft开始找到mid的根
    33. int mid = inLeft;
    34. while (inorder[mid] != root.val){
    35. mid++;
    36. }
    37. //3:递归去生产左右子树
    38. //3.1 当前树的先序遍历的左子树,起止点变为 preLeft+1 ~ preLeft + (左子树一共右多少个点)
    39. //3.2 那左子树右多少个点呢?可以从中序遍历中得到答案 就是 (mid-1) - inLeft + 1 个点。 右-左+1个点。右是mid -1 左是inLeft
    40. //3.3 中序遍历的左子树就是 inLeft ~ (mid -1)
    41. root.left = bulid(preLeft+1,preLeft + (mid -1)-inLeft+1,inLeft,mid-1);
    42. //4:去递归产生右子树
    43. //4.1先序遍历的右子树的起止点,就是上面先序遍历左子树的重点再+1,到 preRight
    44. //4.2 中序遍历右子树的起止点,就是 mid + 1 到 inRight
    45. root.right = bulid((preLeft + (mid -1) - inLeft+1) + 1,preRight,mid + 1,inRight);
    46. return root;
    47. }
    48. }