Oferta de Sword Finger07 Problema Solución-Reconstrucción del árbol binario

Descripción del problema

Ingrese los resultados del recorrido de pedido anticipado y recorrido de orden medio de un árbol binario y, por favor, reconstruya el árbol binario. Suponga que el resultado de entrada del recorrido de preorden y recorrido de orden medio no contiene números repetidos.

Por ejemplo, dado

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]

Devuelve el siguiente árbol binario:

    3
   / \
  9  20
    /  \
   15   7
 

límite:

0 <= 节点个数 <= 5000

Ideas de resolución de problemas:

Para cualquier árbol, la forma de recorrido de preorden es siempre

[ 根节点, [左子树的前序遍历结果], [右子树的前序遍历结果] ]

Es decir, el nodo raíz es siempre el primer nodo en el recorrido de preorden. Y la forma de recorrido en orden es siempre

[ [左子树的中序遍历结果], 根节点, [右子树的中序遍历结果] ]

Siempre que ubiquemos el nodo raíz en el recorrido en orden, entonces podemos saber el número de nodos en el subárbol izquierdo y el subárbol derecho, respectivamente . Dado que las longitudes del recorrido de preorden y el recorrido de orden medio del mismo subárbol son obviamente las mismas, podemos corresponder al resultado del recorrido de preorden y ubicar todos los paréntesis izquierdo y derecho en el formulario anterior.

De esta manera, conocemos los resultados de los recorridos de preorden y de orden medio del subárbol izquierdo, y los resultados de los recorridos de preorden y de orden medio del subárbol derecho. Podemos construir recursivamente el subárbol izquierdo y el subárbol derecho, luego conecte los dos subárboles a las posiciones izquierda y derecha del nodo raíz.

Al ubicar el nodo raíz en el recorrido en orden, un método simple es escanear directamente los resultados de todo el recorrido en orden y encontrar el nodo raíz, pero esto es complejo en el tiempo. Podemos considerar el uso de una tabla hash para ayudarnos a ubicar el nodo raíz rápidamente . Para cada par clave-valor en el mapa hash, la clave representa un elemento (el valor del nodo) y el valor representa su posición en el recorrido de orden medio. Antes del proceso de construcción de un árbol binario, podemos escanear la lista atravesada para construir este mapa hash. En el proceso posterior de construcción del árbol binario, solo necesitamos O (1) tiempo para ubicar el nodo raíz.

Inserte la descripción de la imagen aquí

class Solution {
    
    
    public int [] preOrder;
    public int [] inOrder;
    Map<Integer,Integer> inorderMaps;
    //参数1:前序遍历的起点,参数2:子树序列长度,参数3:中序遍历序列的起点
    public TreeNode build(int pleft,int len,int ileft){
    
    
        //如果长度小于0,直接返回null
        if(len<=0){
    
    
            return null;
        }
        //如果长度刚好等于1,那么就自己一个结点形成了一棵子树
        if(len==1){
    
    //结点值就等于前序遍历的第一个结点值
            TreeNode p=new TreeNode(preOrder[pleft]);
            p.left=null;
            p.right=null;
            return p;       //返回这棵子树
        }else{
    
    
            //如果长度>1,那么就首先在前序遍历中找到根节点
            int rootValue=preOrder[pleft];
            //然后在中序遍历中定位到根节点
            int inRootIndex=inorderMaps.get(rootValue);
            //创建这个根节点
            TreeNode root=new TreeNode(rootValue);
            //计算左子树长度=中序遍历根节点-当前子树中序遍历的起点
            int leftlen=inRootIndex-ileft;
            //计算右子树长度=总结点数-左子树长度-1
            int rightlen=len-leftlen-1;
            //得到左子树
            root.left=build(pleft+1,leftlen,ileft);
            //得到右子树
            root.right=build(pleft+leftlen+1,rightlen,inRootIndex+1);
            //返回根节点
            return root;
        }
    }
    public TreeNode buildTree(int[] preorder, int[] inorder) {
    
    
        //用哈希值存放中序遍历序列的值和下标
        inorderMaps=new HashMap<Integer,Integer>();
        int n=inorder.length;
        if(n==0){
    
           //如果序列长度为0,返回null
            return null;
        }
        //赋值给全局变量,可不用传参
        preOrder=new int[n];
        inOrder=new int[n];
        for(int i=0;i<n;i++){
    
    
            preOrder[i]=preorder[i];
            inOrder[i]=inorder[i];
        }
        for(int i=0;i<n;i++){
    
    
            inorderMaps.put(inorder[i],i);
        }

        TreeNode root=build(0,n,0);
        return root;
    }
}

Supongo que te gusta

Origin blog.csdn.net/qq_39736597/article/details/115029162
Recomendado
Clasificación