LeetCode //C - 141. Ciclo de lista enlazada

141. Ciclo de lista enlazada

Dado el encabezado , el encabezado de una lista vinculada, determine si la lista vinculada tiene un ciclo.

Hay un ciclo en una lista enlazada si hay algún nodo en la lista al que se puede acceder nuevamente siguiendo continuamente el siguiente puntero. Internamente, pos se usa para indicar el índice del nodo al que está conectado el siguiente puntero de la cola. Tenga en cuenta que pos no se pasa como parámetro.

Devuelve verdadero si hay un ciclo en la lista vinculada. De lo contrario, devuelve falso.
 

Ejemplo 1:

inserte la descripción de la imagen aquí

Entrada: head = [3,2,0,-4], pos = 1
Salida: true
Explicación: Hay un ciclo en la lista vinculada, donde la cola se conecta al primer nodo (indexado en 0).

Ejemplo 2:

inserte la descripción de la imagen aquí

Entrada: head = [1,2], pos = 0
Salida: true
Explicación: Hay un ciclo en la lista vinculada, donde la cola se conecta al nodo 0.

Ejemplo 3:

inserte la descripción de la imagen aquí

Entrada: head = [1], pos = -1
Salida: false
Explicación: No hay ningún ciclo en la lista vinculada.

Restricciones:

  • El número de nodos en la lista está en el rango [ 0 , 1 0 4 ] [0, 10^4][ 0 ,1 04 ].
  • − 1 0 5 < = Nodo . valor <= 1 0 5 -10^5 <= Valor.nodo <= 10^51 05<=Nodo . _ _ _ va l _<=1 05
  • pos es -1 o un índice válido en la lista vinculada.

De: LeetCode
Enlace: 141. Ciclo de lista enlazada


Solución:

Ideas:

Idea fundamental:

Imaginemos dos corredores en una pista circular, uno de los corredores (la liebre) es mucho más rápido que el otro (la tortuga). Si comienzan en la misma posición y corren en la misma dirección, el corredor más rápido (liebre) eventualmente dará vuelta al corredor más lento (tortuga). De manera similar, en una lista vinculada, si hay un ciclo, un puntero más rápido eventualmente se encontrará con el puntero más lento dentro del ciclo.

Explicación del código:

1. Inicialización:

  • Tenemos dos punteros: tortuga (que se mueve lentamente) y liebre (que se mueve rápido). Ambos comienzan al principio de la lista vinculada.

2. Movimiento:

  • La tortuga se mueve paso a paso (tortuga = tortuga->siguiente).
  • La liebre avanza dos pasos a la vez (liebre = liebre->siguiente->siguiente).

3. Comprobación del ciclo:

  • Si no hay ningún ciclo en la lista vinculada, la liebre (que se mueve más rápido) eventualmente llegará al final de la lista y encontrará un puntero NULL.
  • Si hay un ciclo, la liebre eventualmente “lamerá” a la tortuga y se encontrarán en algún punto dentro del ciclo.

4. Terminación del bucle:

  • El ciclo continúa mientras liebre y liebre->siguiente no sean NULL.
  • Si los punteros de tortuga y liebre se encuentran (tortuga == liebre), indica la presencia de un ciclo y la función devuelve verdadero.
  • Si el ciclo termina sin que los punteros se encuentren, no hay ciclo y la función devuelve falso.
Código:
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */

bool hasCycle(struct ListNode *head) {
    
    
    if (!head) return false; // If list is empty
    
    struct ListNode *tortoise = head;  // Slow pointer
    struct ListNode *hare = head;      // Fast pointer

    while (hare != NULL && hare->next != NULL) {
    
    
        tortoise = tortoise->next;          // Move slow pointer one step
        hare = hare->next->next;            // Move fast pointer two steps
        
        if (tortoise == hare) return true;  // If they meet, there's a cycle
    }

    return false;  // If loop exits, there's no cycle
}

Supongo que te gusta

Origin blog.csdn.net/navicheung/article/details/132465748
Recomendado
Clasificación