题目
题解
根据前序遍历第一点就是根节点,我们可以根据前序遍历得到根节点然后去中序中找根节点的位置,找到根节点位置就可以根据中序遍历的结果得出左右子树的节点数,然后再根据得出的左右子树的节点数去前序遍历找出左右子树的范围。然后再根据相同的规律在左右子树的范围中利用这个规律去构建,这就是子问题了。可以用递归解决!!!
class Solution1 {
private HashMap<Integer,Integer> indexMap;
public TreeNode buildTree(int[] preorder, int[] inorder) {
int n = preorder.length;
// 构建哈希映射,便于快速找到根节点,值作键,索引做值
indexMap = new HashMap<>();
for (int i = 0; i < n; i++) {
indexMap.put(inorder[i],i);
}
return myBuildTree(preorder,inorder,0,n-1,0,n-1);
}
public TreeNode myBuildTree(int[] preorder, int[] inorder, int pre_left, int pre_right, int ino_left, int ino_right){
if (pre_left > pre_right){
return null;
}
// 先序遍历第一个节点就是根节点
int pre_root = preorder[pre_left];
// 构建根节点
TreeNode root = new TreeNode(pre_root);
// 找出中序遍历的根节点位置
int ino_root = indexMap.get(pre_root);
// 得到左子树的个数
int left_num = ino_root - ino_left;
// 构建左子树
root.left = myBuildTree(preorder,inorder,pre_left+1,pre_left+left_num,ino_left,ino_root-1);
// 构建右子树
root.right = myBuildTree(preorder,inorder,pre_left+left_num+1,pre_right,ino_root+1,ino_right);
return root;
}
}