Ingrese una lista vinculada y genere el k-ésimo nodo desde la parte inferior de la lista vinculada

1. Ideas

Supongamos que K es 2. De acuerdo con la imagen a continuación, podemos ver que el nodo K-ésimo desde abajo es 45.

La premisa a tener en cuenta es que K no puede ser negativo o 0 y no puede exceder el número de nodos en la lista enlazada, porque es necesario asegurarse de que K está dentro del rango de la lista enlazada para encontrar K y luego devolver este nodo.Si no se puede encontrar este nodo, es imposible devolverlo.

Solo después de atravesar todos los nodos es posible encontrar el K-ésimo nodo desde abajo, por lo que definitivamente es necesario usar un bucle para atravesar un nodo por uno.
Luego es para juzgar si el nodo actual es el nodo de destino, si lo es, salte del bucle y regrese a este nodo; si no, continúe buscando el siguiente nodo hasta que la lista enlazada se atraviese por completo.

Lo siguiente a tener en cuenta es la condición final del bucle, es decir, cómo juzgar si el nodo actual es el nodo de destino.
Primero puede definir dos punteros, rápido y lento, ambos apuntan a la posición del nodo principal al principio, pero deje que los rápidos tomen los pasos K-1 primero.

El nodo al que apuntará depende de K. Si K es un número negativo o 0, o excede el número de nodos en la lista enlazada, la
posición apuntada por fast es definitivamente ilegal.


Cuando K es 0, Fast irá a la posición de 0-1, lo que obviamente es ilegal en este momento.



Cuando K es -1, rápido irá a la posición de -1-1, lo que obviamente sigue siendo ilegal en este momento.



Cuando el valor de K excede el número de nodos en la lista enlazada, fast eventualmente irá más allá de la lista enlazada.

Obviamente, las tres situaciones ilegales anteriores no pueden ser utilizadas por mí.

Por lo tanto, al comienzo del código, primero debe determinar si la K actual es legal y, si lo es, luego pasar al siguiente paso; si no lo es, devolver un valor nulo directamente para indicar que el valor actual de K es problemático
.

Después de caminar rápido K-1 pasos, deje que los dos nodos caminen paso a paso. Dado que primero camina rápido, definitivamente caminará más que lento. Cuando el siguiente nodo de fast está vacío, entonces slow apunta al nodo K desde abajo. En este punto, el ciclo ha terminado, solo vuelve a la velocidad después de saltar.



Cuando el valor de K es 1, rápidamente da pasos K-1, es decir, no mueve un paso, y los dos punteros comienzan a moverse juntos en la posición del nodo principal.
Cuando el siguiente nodo de fast está vacío, se puede ver que slow apunta exactamente al último nodo 1 (valor de K).

Esta idea no se ve afectada por los nodos pares e impares, y este método es aplicable independientemente de si los nodos de la lista enlazada son pares o impares.


Cuando rápido ha terminado los pasos K-1, siempre dará un paso más que lento, por lo que cuando el siguiente nodo de rápido está vacío, lento apunta al nodo anterior de rápido, que es el penúltimo nodo (el valor de K).


2. Proceso detallado

1. Primero, juzgue si el valor de K es legal, si no, devuelva un valor nulo directamente.

//k位置不合法
if (k <= 0 || this.head == null) {
    
    
    return null;
}


2. Defina dos punteros, uno llamado rápido y otro lento , y deje que ambos apunten al nodo principal.

//定义一个fast和slow指向head
ListNode fast = this.head;
ListNode slow = this.head;


3. Primero déjese llevar rápidamente por los pasos K-1.

while (k - 1 != 0) {
    
    
    fast = fast.next;
    if (fast == null) {
    
    
        return null;
    }
    k--;
}

Suponiendo que el valor de K en este momento es 2, rápido dará un paso primero. Si el valor actual de K es 1, rápido no dará un paso.
El ciclo anterior no entrará directamente.


Cuando el valor de K es 2, fast irá primero a la posición del segundo nodo.

4. Deje que los dos punteros se muevan al mismo tiempo.

//然后两个一起走
//当fast.next==null的时候,slow所指的位置就是倒数第k个结点
while (fast.next != null) {
    
    
    //两个一起走
    fast = fast.next;
    slow = slow.next;
}
return slow;//此时slow指向的就是倒数第k个结点


El penúltimo nodo es el nodo al que apunta lento en este momento.

código completo

public ListNode findKthToTail(int k) {
    
    
    //k位置不合法
    if (k <= 0 || this.head == null) {
    
    
        return null;
    }

    //定义一个fast和slow指向head
    ListNode fast = this.head;
    ListNode slow = this.head;

    //先让fast走k-1步
    while (k - 1 != 0) {
    
    
        fast = fast.next;
        if (fast == null) {
    
    
            return null;
        }
        k--;
    }

    //然后两个一起走
    //当fast.next==null的时候,slow所指的位置就是倒数第k个结点
    while (fast.next != null) {
    
    
        //两个一起走
        fast = fast.next;
        slow = slow.next;
    }
    return slow;//此时slow指向的就是倒数第k个结点
}



Se puede ver que la prueba de Niuke ha pasado en este momento.
\

Supongo que te gusta

Origin blog.csdn.net/m0_63033419/article/details/131544553
Recomendado
Clasificación