前序遍历的特点:根节点–左子树–右子树
中序遍历的特点:左子树–根节点–右子树
例如:
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
在前序遍历结果中可以找到:这棵树的根 为 3;
再去中序中,可以分辨出9为3的左子树内容,15、20、7为3的右子树内容;
递归去构造3的左子树,3的右子树。
注意一定要给出子树的范围区间。
算法步骤
中序遍历 inorder = [ 9 , 3 , 15 , 20 , 7 ]
left right
1.从前序遍历中找根;
2.在中序遍历结果中找根的位置inrootIdx,
左子树的所有节点区间【left,inrootIdx-1】;
右子树的所有节点区间【inrootIdx+1,,right】;
3.递归创建左子树和右子树。
代码实现
class Solution {
//记录前序中根节点的位置
int index=0;
private TreeNode buildTree(int[] preorder,int[] inorder,int left,int right){
//判断是否已构造完树 || 当前节点是否有子树
if(index>=preorder.length||left>right){
return null;
}
TreeNode root=new TreeNode(preorder[index]);
int inrootIdx=left;
//在中序结果中找到个根节点下标
while(inrootIdx<=right){
if(inorder[inrootIdx]==preorder[index]){
break;
}
inrootIdx++;
}
index++;
//递归构造左子树
root.left=buildTree(preorder,inorder,left,inrootIdx-1);
//递归构造右子树
root.right=buildTree(preorder,inorder,inrootIdx+1,right);
return root;
}
public TreeNode buildTree(int[] preorder, int[] inorder) {
return buildTree(preorder,inorder,0,preorder.length-1);
}
}