Sword se refiere a Offer-52-el nodo de entrada del anillo en la lista vinculada

Descripción del Título

Para una lista vinculada, si contiene un anillo, busque el nodo de entrada del anillo de la lista vinculada; de lo contrario, la salida es nula.

Análisis de ideas

Este método no es nuestro, pero la solución es realmente muy inteligente, por lo que este método se utiliza como contenido de blog.
Dirección del método original: https://blog.nowcoder.net/n/deaa284f105e48f49f38b5d7cb809cd7?f=comment

Descripción de la idea:
suponga que la estructura de la lista vinculada es la siguiente:
Inserte la descripción de la imagen aquí

  • Primero determine si es un anillo. Configure dos punteros, fasth y slwo. Rápido da dos pasos a la vez, lento da un paso a la vez. Rápido definitivamente entrará al anillo antes que lento, y después de muchos ciclos, si finalmente se encuentra lento (asumiendo que el encuentro está en el punto P), significa que rápido ha estado en un círculo y hay un anillo.
    En este proceso slow走过的距离是a+b, fast走过的距离是:a+nb+(n-1)c. (La razón para n veces by n-1 veces c aquí es que debido a que finalmente se encontraron en el punto P, Fast dijo que la distancia recorrida era 1 menos c)
    Entonces la relación de velocidad es la siguiente: 2 (a + b) = a + nb + (n-1) c Se puede ver que n = 2 debido a la relación de igualdad. Y obtén a = c.
  • Entonces se lleva a cabo el juicio de la entrada del anillo.
    Configure slow2 para entrar desde pHead, y slow ahora comienza desde el punto q donde se encuentra. Dado que a = c, cuando lento2 se encuentra con lento, es el punto de entrada del ciclo.

Código

/*
 public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}
*/
public class Solution {
    
    

    public ListNode EntryNodeOfLoop(ListNode pHead)
    {
    
    
        if(pHead == null || pHead.next ==null) return null;
        ListNode fast = pHead;
        ListNode slow = pHead;
        while(fast!=null||fast.next!=null){
    
    
            //由于如果存在环,就会一直循环下去,如果不存在环,就会在满足要求后跳出循环,返回一个null
            fast = fast.next.next;//快指针一次走两步
            slow = slow.next;//慢指针一次走一步
            if(fast==slow){
    
    
                //当快慢指针相遇
                ListNode slow2 = pHead;
                while(slow2!=slow){
    
    
                    slow2 = slow2.next;//slow2指针从phead出进入一次走一步当与slow相遇即为环入口
                    slow = slow.next;
                }
                return slow2;
            }
        }
        return null;
    }
}

Supongo que te gusta

Origin blog.csdn.net/H1517043456/article/details/107509241
Recomendado
Clasificación