首先重要的是要明白前序遍历,和中序遍历的含义;
- 前序遍历:根左右
- 中序遍历:左根右
那么在前序遍历的数组中,第一位一定是根节点,而中序遍历数组中,根节点的左边部分就是该节点的左子树,右边部分就是右子树。
按照这个逻辑,就可以进行递归切分数组。
关键API:
Arrays.copyOfRange(),返回指定索引范围的数组。
代码:
因为每一个递归子树的根节点,都是前序数组的首个元素,所以就是不断递归前序数组,然后拿到每一个递归数组的首个元素,也就是根节点,然后在中序遍历中找到位置然后不断切分两个数组。
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
//前序遍历: 根左右
//中序遍历: 左根右
if(preorder.length==0||inorder.length==0){
return null;
}
if(inorder.length==1){
return new TreeNode(inorder[0]);
}
//首先前序遍历的第一个元素 肯定是根节点 那么找到根节点后
//在中序遍历的数组中找到根节点 那么根节点的左边部分就是根节点的左子树 右边部分就是根节点的右子树
int rootv=preorder[0]; //根节点
int index=0; //根节点索引
for(int i=0;i<inorder.length;i++){
if(rootv==inorder[i]){
//记录当前的根节点索引
index=i;
break;
}
}//到此已经在中序遍历数组中找到根节点 然后分为两部分
//接下来就是递归数组确定元素
TreeNode root=new TreeNode(rootv);
//然后中序遍历数组就可以 左右子树范围可以找到 然后到前序遍历中找到对应的子树范围
int []sonleft=Arrays.copyOfRange(inorder,0,index); //左子树
int []sonright=Arrays.copyOfRange(inorder,index+1,inorder.length);;//右子树
//然后在前序遍历中找到对应的数组范围
int []qianleft=Arrays.copyOfRange(preorder,1,sonleft.length+1);//前序遍历 左子树部分
int []qianright=Arrays.copyOfRange(preorder,sonleft.length+1,preorder.length); //右子树部分
root.left=buildTree(qianleft,sonleft);
root.right=buildTree(qianright,sonright);
return root;
}
}