Le sujet est de LeetCode
D'autres solutions ou code source sont accessibles: tongji4m3
la description
L'arbre binaire est construit selon le parcours de pré-ordre et d'ordre médian d'un arbre.
Remarque:
vous pouvez supposer qu'il n'y a pas d'éléments en double dans l'arborescence.
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
Idées
Pour le tableau [lo, hi] parcouru en pré-ordre et en ordre intermédiaire:
- Le nœud racine du précommande est lo, et le nœud racine de l'ordre du milieu est i
- Le sous-arbre gauche du précommande est [lo + 1, i], le sous-arbre droit est [i + 1, hi]
- Le sous-arbre gauche de l’ordre du milieu est [lo, i-1] et le sous-arbre droit est [i + 1, hi]
Par conséquent, le nœud racine peut être construit en premier, puis ses nœuds gauche et droit peuvent être construits selon les tableaux gauche et droit dans le pré-ordre, l'ordre du milieu, et continuer à récurer ...
détail
- Notez que la pré-commande après plusieurs récursions, le tableau dans l'ordre peut ne pas être symétrique de haut en bas, donc leur index d'index doit être divisé en preIndex, inIndex
- Utilisez le stockage de carte pour accélérer
Code
/**
* look 用map存储加快速度
树中没有重复元素
用map存储inorder数组的值和对应索引
方便找到根节点位置
*/
private Map<Integer, Integer> map = new HashMap<>();
public TreeNode buildTree(int[] preorder, int[] inorder)
{
for (int i = 0; i < inorder.length; i++)
{
map.put(inorder[i], i);
}
return buildTree(preorder, 0, preorder.length - 1, inorder, 0, inorder.length - 1);
}
private TreeNode buildTree(int[] preorder, int preLo, int preHi, int[] inorder, int inLo, int inHi)
{
if (preLo > preHi || inLo > inHi)
{
return null;
}
//找到根节点在中序遍历的索引位置
int inIndex = map.get(preorder[preLo]);
//look,i在经过几次之后,只是对应了inorder的i,但是对于preorder,应该只是一个偏移量
//inIndex - inLo代表左子树的个数,preIndex则是前序遍历左子树的最后一个元素
int preIndex = preLo + inIndex - inLo;
TreeNode root = new TreeNode(preorder[preLo]);
root.left = buildTree(preorder, preLo + 1, preIndex, inorder, inLo, inIndex - 1);
root.right = buildTree(preorder, preIndex + 1, preHi, inorder, inIndex + 1, inHi);
return root;
}