Prefacio:
Hermanos, programación, cuando terminemos de aprender estructuras de datos, tendrán una sensación de luz. Es una entrada real a la programación, por lo que es particularmente importante sentar una buena base para las estructuras de datos. En el último capítulo, pasamos a la lista enlazada. Aunque sabemos qué es una lista enlazada y cuál es la estructura de una lista enlazada, está lejos de ser suficiente. Solo sabemos un poco al respecto. Debemos hacer más preguntas. , y poco a poco iremos sintiendo que todo es muy sencillo en el proceso de hacer las preguntas. ¡Ahora hagamos algunas preguntas clásicas de prueba de superficie de cadena! ! ! ! ! !
1. Preguntas de prueba de superficie de cadena
1. Invertir una lista enlazada individualmente
Cada nodo no cambia, solo modifique el punto actual de cada nodo
Mira el análisis de la imagen:
análisis del problema:
Cada nodo no cambia, solo necesita modificar el punto actual de cada nodo, el primer nodo apunta para convertirse en nulo y el segundo nodo apunta al primer nodo.
Explicación del problema:
Necesitamos definir cuatro variables de nodo
La variable principal es igual al nodo principal.
cur = cabeza
anterior = nulo
curSiguiente = cur.siguiente
Paso 1: curNext = cur.next
Paso 2: cur.next = anterior
Paso 3: anterior = actual
Paso 4: cur = curSiguiente
A ver como va el diagrama
Paso 1: curNext = cur.next
Paso 2: cur.next = anterior
Paso 3: anterior = actual
Paso 4: cur = curSiguiente
Estos cuatro pasos lo convierten en un ciclo, tomemos otro ciclo para que todos lo vean.
Paso 5: curNext = cur.next
Paso 6: cur.next = anterior
Paso 7: anterior = actual
Paso 8: cur = curSiguiente
Después de los dos bucles, creo que todo el mundo puede verlo muy claramente. Dado que es un bucle, debe haber una condición de terminación, para que podamos echar un vistazo. Cuando cur llega al último byte, todavía necesitamos cur.next = prev , si va más allá, cur es nulo, y cuando es nulo, se acaba lo contrario. Entonces, la condición de terminación de nuestro bucle es cur != null. Además, también tenemos que juzgar si el encabezado que siempre apunta al nodo principal no es nulo, si es nulo, no existe tal lista enlazada, y es suficiente devolver nulo directamente. Una vez completada la inversión, el último nodo se convierte en el nodo principal, por lo que podemos volver a la anterior, luego podemos escribir el código.
Código:
lass Solution { public ListNode reverseList(ListNode head) { if (head == null) { return null; } ListNode cur = head; ListNode prev = null; while (cur != null) { ListNode cutNext = cur.next; cur.next = prev; prev = cur; cur = cutNext; } return prev; } }
Haga clic en https://leetcode-cn.com/problems/reverse-linked-list/description/ para vincular el título anterior, todo el mundo debe abrir el enlace y hacerlo usted mismo.
2. Dada una lista enlazada simple no vacía con cabeza de nodo principal, devuelva el nodo medio de la lista enlazada. Si hay dos nodos intermedios, devuelve el segundo nodo intermedio.
Análisis de dibujo:
Análisis del problema: Si devuelve el número impar, devuelve el nodo medio, y si el número par es el segundo nodo medio, es decir, el número par devuelve el tercero.
Explicación del problema:
Del mismo modo, definamos dos variables de referencia
Tanto las variables de referencia rápidas como las lentas son iguales al nodo principal principal
Como se muestra en la figura:
Dejamos que fast tome dos pasos a la vez, y slow tome dos pasos a la vez.En casos extraños: fast.next es nulo, y la posición de slow es el nodo intermedio. Caso de números pares: rápido es nulo y bajo es la posición del nodo intermedio. La razón es ¿por qué? Si dos van al mismo tiempo, la velocidad del rápido es el doble que la del lento, por lo que la distancia también es el doble, cuando uno llega al final, el otro está a la mitad de la distancia. Con tal idea, podemos escribir código. De manera similar, primero debemos juzgar si la lista enlazada es nula y devolver nulo directamente si es nulo.
Código:
class Solution { public ListNode middleNode(ListNode head) { if(head == null){ return null; } ListNode fast = head; ListNode slow = head; while(fast != null && fast.next != null ){ fast = fast.next.next; slow = slow.next; } return slow; } }
Leetcode https://leetcode-cn.com/problems/middle-of-the-linked-list/description/
3. Ingrese una lista vinculada y genere el k-ésimo nodo desde la parte inferior de la lista vinculada
Análisis de dibujo:
Explicación del problema:
Del mismo modo, definamos dos variables de referencia
Tanto las variables de referencia rápidas como las lentas apuntan al nodo principal
Como se muestra en la figura:
Si queremos encontrar el K-ésimo penúltimo, necesitamos tomar K-1 pasos desde el K-ésimo hasta el penúltimo 1, así que primero vamos a tomar rápidamente los pasos K-1, y cuando se completan los pasos K-1, rápido apunta al penúltimo Durante un tiempo, luego lento es el último K-ésimo que estamos buscando.Si rápido termina K-1 pasos y rápido no apunta al último, entonces en este momento dejamos que rápido y lento retrocedan juntos, siempre son peores Después del paso K-1, cuando rápido va al último, el nodo al que apunta lento en este momento es el último K-ésimo que estamos buscando. Aquí también necesitamos juzgar K. Si K<=0 o k> la longitud de la lista enlazada, podemos devolver nulo directamente.
Código:
public class Solution { public ListNode FindKthToTail(ListNode head,int k) { if(k <= 0 || head == null){ return null; } ListNode fast = head; ListNode slow = head; while(k-1 != 0){ fast = fast.next; if(fast == null){ return null; } k--; } while(fast.next != null){ fast = fast.next; slow = slow.next; } return slow; } }
4. Combine las dos listas ordenadas en una nueva lista ordenada y regrese. La nueva lista enlazada se forma empalmando todos los nodos de las dos listas enlazadas dadas.
Análisis de dibujos: estas son nuestras dos listas enlazadas
Explicación del problema:
De manera similar, primero defina dos variables de referencia headA y headB para que apunten a los nodos principales de las dos listas vinculadas, respectivamente.
Defina un nodo virtual, suponiendo que se llame newHead, y defina una variable de referencia tmp igual a newHead
Primero, comparemos el tamaño de headA y headB. Si headA.val<headB.val, entonces tmp.next sea igual a headA
Debido a que 12 es pequeño, entonces hagamos headA = headA.next. Si luego encuentra un número mayor que 12, se colocará después de 12, así que hacemos tmp = tmp.next,
En este momento, compare headA y headB.Si headA.val>headB.val, entonces sea tmp.next = headB, luego sea headB = headB.next, tmp = tmp.next
Esto forma uno de nuestros bucles. Cuando headA y headB no son nulos, podemos continuar el bucle. Cuando el bucle termina, headA es nulo o headB es nulo. Cuando headA es nulo, dejamos tmp.next = headB , cuando headB es nulo, dejamos tmp.next = headA,
Código:
lass Solution { public ListNode mergeTwoLists(ListNode headA, ListNode headB) { ListNode newhead = new ListNode(-1); ListNode tmp = newhead; while (headA != null && headB != null) { if (headA.val < headB.val) { tmp.next = headA; headA = headA.next; tmp = tmp.next; } else { tmp.next = headB; headB = headB.next; tmp = tmp.next; } } if(headA == null){ tmp.next = headB; } if(headB == null){ tmp.next = headA; } return newhead.next; } }
Leetcode https://leetcode-cn.com/problems/merge-two-sorted-lists/description/
Por cuestiones de tiempo: primero voy a perforar estas 4 preguntas de la entrevista.Estas 4 preguntas de la entrevista son preguntas de entrevista relativamente clásicas, que serán muy útiles para nuestro estudio de la lista enlazada. Aprender estructuras de datos se trata de hacer más preguntas para que pueda comprender completamente el conocimiento de las estructuras de datos. Es demasiado tarde hoy, sigamos dándole más preguntas para la entrevista mañana. Si tiene alguna pregunta, puede enviarme un mensaje privado. Si tiene alguna pregunta, puede señalarla. Aprenderé con una mente abierta y espero progresar con usted.