[LeetCode] C ++: árbol de problemas intermedio 105. Construya un árbol binario a partir de la secuencia transversal de orden medio y de preorden

105. Construya un árbol binario a partir de una secuencia transversal de orden medio y de preorden

Dificultad media 930

El árbol binario se construye de acuerdo con el recorrido de preorden y el recorrido de orden medio de un árbol.

Nota:
puede asumir que no hay elementos duplicados en el árbol.

Por ejemplo, dado

Preorder recorrido preorden = [3,9,20,15,7] Inordenado 
recorrido inorden = [9,3,15,20,7]

Devuelve el siguiente árbol binario:

    3 
   / \ 
  9 20 
    / \ 
   15 7

Análisis de ideas:

La idea principal es esta, el recorrido de orden medio puede obtener el nodo raíz de un árbol, y luego, a través del recorrido de preorden y el nodo raíz, puede conocer el número de nodos en los subárboles izquierdo y derecho del árbol, y luego continuar. para realizar una operación recursiva Se pueden construir un subárbol izquierdo y un subárbol derecho, y finalmente conectarlos al nodo raíz para formar un árbol binario.

Cabe señalar que la ubicación del mapeo, es decir, la ubicación del nodo raíz, puede considerarse como la ubicación del nodo raíz de cada subárbol. La solución oficial al problema es poner la secuencia del recorrido de orden medio en la tabla hash, lo que puede ayudar a encontrar rápidamente el nodo raíz.

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    unordered_map<int, int> index;

    TreeNode* myBuildTree(const vector<int>& preorder, const vector<int>& inorder, int pre_left, int pre_right, int in_left, int in_right){
        if (pre_left > pre_right){
            return nullptr;
        }
        int pre_root = pre_left;//前序遍历中根节点位置
        int in_root = index[preorder[pre_root]];//中序遍历中根节点位置

        TreeNode* root = new TreeNode(preorder[pre_root]);
        int size_left_subTree = in_root - in_left; //两位置只差为左子树节点个数

        root->left = myBuildTree(preorder, inorder, pre_left+1, pre_left+ size_left_subTree, in_left,  in_root-1);
        root->right = myBuildTree(preorder, inorder, pre_left+size_left_subTree+1, pre_right, in_root+1, in_right);
        return root;
    }

    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
        int n = preorder.size();
        for(int i = 0; i < n; i++){
            index[inorder[i]] = i; 
        }
        return myBuildTree(preorder, inorder, 0, n-1, 0, n-1);
    }
};

 

 

 

Epílogo:

Ha pasado mucho tiempo, ahora estoy empezando a practicar el algoritmo de nuevo, ¡vamos!

 

 

Supongo que te gusta

Origin blog.csdn.net/weixin_44566432/article/details/114847205
Recomendado
Clasificación