Lista enlazada de LeetCode # 141 Lista enlazada de ciclo-anillo

1. Título

Dada una lista vinculada, determine si hay anillos en la lista vinculada.

Para representar los anillos en una lista vinculada dada, usamos la posición entera para indicar la posición en la lista vinculada donde está conectada la cola de la lista vinculada (el índice comienza en 0). Si pos es -1, no hay anillo en la lista.

Ejemplo 1:

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

Ejemplo 2

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

Ejemplo 3

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

Avanzado: ¿Puede resolver este problema con la memoria O (1) (es decir, constante)?

En segundo lugar, la solución

  • Solución 1: tabla hash

Iterar sobre todos los nodos y almacenar la referencia de cada nodo en la tabla hash. Si la referencia del nodo actual ya existe en la tabla hash, indica que la lista vinculada es una lista vinculada circular y devuelve verdadero; de lo contrario, atraviesa hasta el final, es decir, el siguiente nodo del nodo es nulo y la lista vinculada no es una lista vinculada circular, y devuelve falso.

Complejidad del tiempo: O (n), complejidad del espacio: O (n).

function hasCycle($head) {
    $hashMap = [];
    $curr = $head;
    while ($curr != null && $curr->next != null) {
        if (in_array($curr, $hashMap)) {
            return true;
        } 
        $hashMap[] = $curr;
        $curr = $curr->next;
    } 
    return false;
}
  • Solución 2: puntero doble-puntero rápido

Puntero rápido: dos pasos a la vez
Puntero lento: un paso a la vez

Supongamos que una pista circular, dos atletas A y B, A está un paso por delante de B:
en un círculo, la A rápida, después de correr n vueltas, debe cumplir con la B lenta,
correspondiente a la lista vinculada, es decir, dos Coincidencia de puntero

Si no es un círculo, la A rápida debe llegar al final primero, lo que indica que no hay anillo:
la lista vinculada correspondiente es el puntero final que apunta a nulo

Complejidad del tiempo: O (n), complejidad del espacio: O (1).

function hasCycle($head) {
    if ($head == null || $head->next == null) {
        return false;
    }
    //快慢指针
    $slow = $head;
    $fast = $head->next;
    while ($slow != $fast) {
        //没有环,fast走到链表尾部,fast为空或者fast的next为空
        if ($fast == null || $fast->next == null) {
            return false;
        }
        $slow = $slow->next;
        $fast = $fast->next->next;
    }
    return true;
}

El método del puntero rápido y lento se realiza después de leer la solución, y al principio no está claro: ¿por qué la velocidad del puntero rápido 2 y la velocidad del puntero lento 1? ¿No puede la velocidad del puntero rápido ser 3 o mayor?

Haga un dibujo varias veces, probablemente entienda:
rápido toma 2 pasos, lento toma 1 paso, si hay un anillo, entonces rápido encontrará lento o rápido irá atrás lento.

Si el rápido camina lento, la distancia entre los dos punteros disminuirá en 1 cada vez que caminen los dos punteros, y finalmente los dos punteros definitivamente se encontrarán sin importar cuán lejos estén.

Pero si rápido es 3 pasos y lento es 1 paso, el mismo es el caso al frente. La distancia entre ellos se reduce en 2 cada vez, y finalmente rápido va al frente de lento nuevamente, por lo que si rápido se establece en 3, se necesita un juicio adicional. condiciones, ver el siguiente código whileal.

function hasCycle($head) {
    if ($head == null || $head->next == null) {
        return false;
    }
    //快慢指针
    $slow = $head;
    $fast = $head->next->next;
    while ($slow != $fast || $slow->next != $fast) {
        //没有环,fast走到链表尾部,fast为空或者fast的next为空
        if ($fast == null || $fast->next == null) {
            return false;
        }
        $slow = $slow->next;
        $fast = $fast->next->next->next;
    }
    return true;
}

Supongo que te gusta

Origin www.cnblogs.com/sunshineliulu/p/12688898.html
Recomendado
Clasificación