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:
- 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 procesoslow走过的距离是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;
}
}