package treeAndRecursion.code105;import treeAndRecursion.TreeNode;public class Solution { int[] preorder; int[] inorder; public TreeNode buildTree(int[] preorder, int[] inorder) { //作为类成员变量,省着传了 this.preorder = preorder; this.inorder = inorder; //让全部整段去构建 return bulid(0, preorder.length-1,0,inorder.length-1); } /** * 用先序遍历的一段 和 中序遍历的一段 去还原当前这一部分树(子树) * @param preLeft 先序遍历的左起始点 * @param preRight 先序遍历的右结束点 * @param inLeft 中序遍历的左起始点 * @param inRight 中序遍历的右结束点 * @return */ public TreeNode bulid(int preLeft,int preRight,int inLeft,int inRight){ //递归结束条件,当left > right if(preLeft > preRight){ return null; } // 1 : 先序遍历是 根 左 右,所以先序遍历第一个值 preLeft 就是根 TreeNode root = new TreeNode(preorder[preLeft]); // 2 : 确立了根之后。去找左右子树。 // 2.1:因为中序遍历是 左 根 右,所以在中序遍历中找到根 mid 就是中序遍历中根的下标 // 2.2:根左边就是左子树 inLeft ~ (mid -1) // 2.3:根右边就是右子树 (mid + 1) ~ inRight // 从inLeft开始找到mid的根 int mid = inLeft; while (inorder[mid] != root.val){ mid++; } //3:递归去生产左右子树 //3.1 当前树的先序遍历的左子树,起止点变为 preLeft+1 ~ preLeft + (左子树一共右多少个点) //3.2 那左子树右多少个点呢?可以从中序遍历中得到答案 就是 (mid-1) - inLeft + 1 个点。 右-左+1个点。右是mid -1 左是inLeft //3.3 中序遍历的左子树就是 inLeft ~ (mid -1) root.left = bulid(preLeft+1,preLeft + (mid -1)-inLeft+1,inLeft,mid-1); //4:去递归产生右子树 //4.1先序遍历的右子树的起止点,就是上面先序遍历左子树的重点再+1,到 preRight //4.2 中序遍历右子树的起止点,就是 mid + 1 到 inRight root.right = bulid((preLeft + (mid -1) - inLeft+1) + 1,preRight,mid + 1,inRight); return root; }}