/** * Definition for binary tree * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ //Arrays.copyOfRange(T[ ] original,int from,int to) 需要import java.util.Arrays; //将一个原始的数组original,从下标from开始复制,复制到上标to,生成一个新的数组。左闭右开,包含上标不包括下标 import java.util.Arrays; public class Solution { public TreeNode reConstructBinaryTree(int [] pre,int [] in) { //递归调用的终止条件 if(pre.length == 0 || in.length == 0){ return null; } //由前序遍历得到该二叉树的根结点 TreeNode root = new TreeNode(pre[0]); //在中序遍历中找根结点位置,进行左右子树的划分 for(int i = 0; i < in.length; i++){ if(root.val == in[i]) { //将左子树看成一棵二叉树调用该方法,可以得到左子树根结点,即上面根结点的左子结点 root.left = reConstructBinaryTree(Arrays.copyOfRange(pre,1,i+1),Arrays.copyOfRange(in,0,i)); //将右子树看成一棵二叉树调用该方法,可以得到右子树根结点,即上面根结点的右子结点 root.right = reConstructBinaryTree(Arrays.copyOfRange(pre,i+1,pre.length),Arrays.copyOfRange(in,i+1,in.length)); //找到根结点位置便跳出循环 break; } } //返回根结点 return root; } }
方法二:
//利用原理,先序遍历的第一个节点就是根。在中序遍历中通过根 区分哪些是左子树的,哪些是右子树的 //左右子树,递归 HashMap<Integer, Integer> map = new HashMap<>();//标记中序遍历 int[] preorder;//保留的先序遍历 public TreeNode buildTree(int[] preorder, int[] inorder) { this.preorder = preorder; for (int i = 0; i < preorder.length; i++) { map.put(inorder[i], i); } return recursive(0,0,inorder.length-1); } /** * @param pre_root_idx 先序遍历的索引 * @param in_left_idx 中序遍历的索引 * @param in_right_idx 中序遍历的索引 */ public TreeNode recursive(int pre_root_idx, int in_left_idx, int in_right_idx) { //相等就是自己 if (in_left_idx > in_right_idx) { return null; } //root_idx是在先序里面的 TreeNode root = new TreeNode(preorder[pre_root_idx]); // 有了先序的,再根据先序的,在中序中获 当前根的索引 int idx = map.get(preorder[pre_root_idx]); //左子树的根节点就是 左子树的(前序遍历)第一个,就是+1,左边边界就是left,右边边界是中间区分的idx-1 root.left = recursive(pre_root_idx + 1, in_left_idx, idx - 1); //由根节点在中序遍历的idx 区分成2段,idx 就是根 //右子树的根,就是右子树(前序遍历)的第一个,就是当前根节点 加上左子树的数量 // pre_root_idx 当前的根 左子树的长度 = 左子树的左边-右边 (idx-1 - in_left_idx +1) 。最后+1就是右子树的根了 root.right = recursive(pre_root_idx + (idx-1 - in_left_idx +1) + 1, idx + 1, in_right_idx); return root; }