LeetCode Sword se refiere a la Oferta 68-II. El ancestro común más cercano del árbol binario

Enlace
a la pregunta original Hice una búsqueda del antepasado común más cercano del árbol de búsqueda binaria antes. Debido a la naturaleza ordenada del árbol de búsqueda, es fácil de hacer. Pero este problema es reemplazado por un árbol binario general, que es un poco más complicado de forma recursiva.

Leer las obras maestras de los grandes dioses en los comentarios , es demasiado nb. En esencia, es lo mismo que mi idea. Todos están mirando si el nodo de destino está en los subárboles izquierdo y derecho del nodo raíz. Preste atención a la escritura del valor de retorno y determine la estructura A? B: C donde se pueden anidar B y C. Estructura, aprendida.

Dar el código:

struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q){
    
    
    /* 二叉树为空或者结点 p/q 为根结点 */
    if (root == NULL || root == p || root == q) {
    
    
        return root;
    }

    /* 在根结点的左右子树查找 */
    struct TreeNode *left = lowestCommonAncestor(root->left, p, q);
    struct TreeNode *right = lowestCommonAncestor(root->right, p, q);
    
    /* 结点 p/q 不在左子树中,就在右子树中查找,如果能找到,就返回在右子树中找到的结点(反之亦然) */
    /* 结点 p/q 分别存在左右两颗子树, 根结点为最近公共祖先 */
    /* 结点 p/q 在左右子树都找不到,则它们没有最近公共祖先 */
    return left == NULL ? right : right == NULL ? left : root;     
}

Lo siguiente es mi primer pensamiento:

  1. Cada nodo juzga una vez, si hay un nodo de destino en el subárbol con este nodo como nodo raíz, y la función isThere () devuelve el valor verdadero de sí o no.
  2. Comience desde el nodo raíz. Si es así, observe el valor de retorno de la función isThere () de sus subárboles izquierdo y derecho.
  3. Si el nodo secundario común no es uno de los nodos de destino, al menos uno de los valores de la función isThere () del subárbol es verdadero, ingrese al subárbol cuyo valor de retorno es verdadero y de forma recursiva ingrese al árbol cuyo valor de retorno isThere () sea verdadero izquierda y derecha. El valor de retorno de isThere () del subárbol es verdadero. Demuestre que este nodo se encuentra y se asigna al resultado de la variable global.
  4. Si el nodo secundario común es uno de los nodos de destino, haga un juicio antes de regresar al nodo. Si es así, asigne el nodo raíz actual al resultado.
  5. Devolver resultado.

Vale la pena señalar que cuando se actualiza el resultado, la función se actualiza en el orden de salida de la pila, por lo que la situación mencionada en el punto 4 debe colocarse antes de la devolución.

Pero no es de extrañar que se haya agotado el tiempo jajaja, porque hay demasiadas recursiones, la doble recursividad es un poco una escultura de arena, pero parece que vale la pena registrar esta idea.

Dé el código (cambie a lenguaje C esta vez):

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */

struct TreeNode* result;

// 判断目标子节点是否在该以 root 为根的子树中,如果在,就返回true,不在返回false
bool isThere(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q){
    
    
    if(!root) return false;
    if(root->val == p->val || root->val == q->val) return true;
    return isThere(root->left,p,q) || isThere(root->right,p,q);
}

struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q){
    
    
    if(isThere(root, p, q)){
    
       // 只有此节点中包含有目标节点才能进一步判断
        if(isThere(root->left,p,q)  && isThere(root->right, p, q)) result = root;   // 如果左右子节点中均存在目标节点,证明这个是他们的公共祖先节点
        else if(isThere(root->left, p, q)) lowestCommonAncestor(root->left, p, q);    // 进入左右子节点中isThere函数返回值是true的分支判断
        else if(isThere(root->right, p, q)) lowestCommonAncestor(root->right, p, q);
    }
    if(root->val == p->val || root->val == q->val) result = root;  // 看根节点是否是目标节点两个之间的一个
    return result;
}

Supongo que te gusta

Origin blog.csdn.net/qq_43078427/article/details/110331084
Recomendado
Clasificación