题目描述
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
解法一:递归+哈希
- 先将inorder存入哈希表中,方便查找
- 调用创建二叉树函数
- 利用preorder设置根节点,在inorder找到根节点,区分左右子树
- 找出左右子树的起点终点
- 分别调用左右子树
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
int n=preorder.length,m=inorder.length;
Map<Integer,Integer> map=new HashMap<>();
for(int i=0;i<n;i++){
map.put(inorder[i],i);
}
return buildTreeHelper(preorder,0,n-1,inorder,0,m-1,map);
}
public TreeNode buildTreeHelper(int[] preorder,int p_start,int p_end,int[] inorder,int i_start,int i_end,Map<Integer,Integer> map){
//终止条件
if(p_start>p_end||i_start>i_end){
return null;
}
//创建根节点
int root_val=preorder[p_start];
TreeNode root=new TreeNode(root_val);
//找出inorder的根所在位置,用于区分左右子树
int root_index=map.get(root_val);
//用len记录左子树长度
int len=root_index-i_start;
//pre 起点+1为新起点,起点+len为终点
//in 起点不变,终点为根位置-1
root.left=buildTreeHelper(preorder,p_start+1,p_start+len,inorder,i_start,root_index-1,map);
//pre 起点为(起点+len)+1 终点不变
//in 起点为根位置+1,终点不变
root.right=buildTreeHelper(preorder,p_start+len+1, p_end,inorder,root_index+1,p_end,map);
return root;
}
}