Java encuentra el ancestro común más cercano de dos nodos de un árbol binario

El ancestro común más cercano del árbol binario.

Descripción del problema

Dado un árbol binario, encuentre el ancestro común más cercano de dos nodos especificados en el árbol.
La definición del ancestro común más cercano en la Enciclopedia Baidu es:

"Para dos nodos p, q de un árbol con raíz T, el ancestro común más cercano se representa como un nodo x, satisfaciendo que x es el ancestro de p, q y la profundidad de x es tan grande como sea posible (un nodo también puede ser su propio antepasado).

ejemplo

inserte la descripción de la imagen aquíinserte la descripción de la imagen aquíinserte la descripción de la imagen aquí

Título original DO enlace

https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/submissions/

código de respuesta

método uno

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    
    
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    
    
        if(root == null){
    
    //如果是一颗空树,那么也就没有什么祖先结点的说法了
            return null;
        }
        if(root == p || root == q){
    
    //p,q其中一个是根节点,那么祖先就是根节点
        //这一行代码也是用来递归寻找p,q结点的   3
            return root;
        }
        //往左子树去找p,q结点
        TreeNode leftRet = lowestCommonAncestor(root.left,p,q);
        //往右子树去找p,q结点
        TreeNode rightRet = lowestCommonAncestor(root.right,p,q);

        if(leftRet != null && rightRet != null){
    
     
            return root;//说明pq分布分布在root的左右两边,那么他们的公共结点一定是root结点  1
        }
        else if(leftRet != null){
    
    
            return leftRet;//说明pq都分布在根节点左边,那么一直往下找,无论pq谁先被找到谁就是祖先结点   2
        }
        else if(rightRet != null){
    
    
            return rightRet;//说明pq都分布在根节点右边边,那么一直往下找,无论pq谁先被找到谁就是祖先结点
        }
        //最后一种情况,就是qp根本没有公共祖先
        return null;      
    }
}

La siguiente figura es la situación del código anterior 1
inserte la descripción de la imagen aquí

La siguiente figura es la situación del código anterior 2

inserte la descripción de la imagen aquíLa siguiente figura es la situación del código anterior 3
inserte la descripción de la imagen aquí

Método dos

Además, la ruta desde el nodo raíz a los nodos q y p se puede encontrar primero y luego se almacena en una lista enlazada, y luego se convierte en un problema encontrar el nodo común de las dos listas enlazadas.
Pero esta idea tiene un problema por resolver, es decir, cómo encontrar la ruta desde el nodo raíz de la ruta hasta un nodo determinado. El método es usar la pila para empujar primero un nodo que no está seguro de si está en la ruta y, a continuación, recorra su subárbol. Si no se encuentra ningún nodo de destino, confirme que el nodo no se encuentra en la ruta y vuelva a aparecer. De hecho, es recorrido primero en profundidad.El
código específico es el siguiente

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
import java.util.Deque;
import java.util.LinkedList;
class Solution {
    
    
    public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
    
    
        Deque<TreeNode> stack1 = new LinkedList<>();
        getPath(root,p,stack1);
        Deque<TreeNode> stack2 = new LinkedList<>();
        getPath(root,q,stack2);

        //判断栈的大小
        int length1 = stack1.size();
        int length2 = stack2.size();
        int length = 0;
        if(length1>length2){
    
    
            length = length1 - length2;
            while(length != 0){
    
    
                stack1.pop();
                length--;
            }
        }
        else{
    
    
            length = length2 - length1;
            while(length != 0){
    
    
            stack2.pop();
            length--;
            }
        }
        //栈元素个数都一样了
        while(!stack1.isEmpty() && !stack2.isEmpty()){
    
    
            if(stack1.peek() != stack2.peek()){
    
    
                stack1.pop();
                stack2.pop();
            }
            else{
    
    
                return stack1.peek();
            }
        
        }
        return null;    
        
    }
    public  Boolean getPath(TreeNode root,TreeNode node,Deque<TreeNode> stack){
    
    
        if(root == null || node == null){
    
    
            return false;
        }
        stack.push(root);//根节点肯定在路径里面,第一个压入栈中,
        if(root == node){
    
    
            return true;
        }
        boolean ret1 = getPath(root.left,node,stack);//之后先把寻找过程中的结点都先压入栈中
        if(ret1 == true){
    
    
            return true;//往左边找找到了
        }
        boolean ret2 = getPath(root.right,node,stack);
        if(ret2 == true){
    
    
            return true;//往右边找找到了
        }
        //往左和往右都没找到,说明这个结点不在路径上,所以把这个点给弹出
        stack.pop();
        return false;
        
    }
}

Supongo que te gusta

Origin blog.csdn.net/baixian110/article/details/130954588
Recomendado
Clasificación