Sitio web de preguntas de pincel: Leetcode
Dificultad: Moderada
Idioma: pitón
Plan : De fácil -> a medio -> a difícil.
1. 19 Eliminar el nodo N de la parte inferior de la lista vinculada
1.1 Descripción del tema
Dada una lista vinculada, elimine el enésimo último nodo de la lista vinculada y devuelva el nodo principal de la lista vinculada.
- Ejemplo 1
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
- Ejemplo 2
输入:head = [1], n = 1
输出:[]
- Ejemplo 3
输入:head = [1,2], n = 1
输出:[1]
1.2 Pensamiento y análisis
(No entiendo muy bien esta pregunta, ¡pero será más clara después de leer la respuesta!)
Generalmente, para encontrar una posición especial en la lista enlazada , primero considere usar el método de puntero rápido y lento y encuentre su predecesor. Esta pregunta dice que elimine el penúltimo n
nodo, de hecho, también puede entenderse como eliminar el primer L-N+1
nodo.
La lista enlazada debe ser una forma de apuntar a la siguiente. Si necesita eliminar un nodo, necesita encontrar su nodo predecesor. Sin embargo, cuando la longitud de la lista enlazada es 1, es decir, solo el nodo principal, no tiene predecesor y es propensa a errores. Por lo general, se agrega un nodo ficticio antes del nodo principal y su next
puntero apunta al nodo principal . de la lista enlazada. Es decir, no hay necesidad de hacer un juicio especial sobre el nodo principal, de lo contrario, es necesario juzgar las condiciones de contorno.
head_dumy = ListNode() #添加哑节点
head_dumy.next = head #哑节点指向头节点
slow, fast = head_dummy, head_dummy ##快慢指针指向哑节点
Idea de código:Deje que el puntero rápido n
avance , y luego los punteros rápido y lento avancen juntos hasta que apunte el puntero rápido Null
, luego el nodo señalado por el puntero lento en este momento es el nodo que se eliminará, pero es necesario conocer el nodo predecesor de el nodo eliminado para eliminarlo.
Puntero rápido avanza n pasos
while(n!=0): #fast先往前走n步
fast = fast.next
n -= 1
Luego, las manos rápidas y lentas se mueven al mismo tiempo hasta que la mano rápida llega al final.
while(fast.next!=None):
slow = slow.next
fast = fast.next
Luego, elimine el nodo backdrive del puntero lento (es decir, deje que apunte al nodo backdrive del backdrive)
slow.next = slow.next.next #删除
El código completo es el siguiente
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
head_dummy = ListNode()
head_dummy.next = head
slow, fast = head_dummy, head_dummy
while(n!=0): #fast先往前走n步
fast = fast.next
n -= 1
while(fast.next!=None):
slow = slow.next
fast = fast.next
#fast 走到结尾后,slow的下一个节点为倒数第N个节点
slow.next = slow.next.next #删除
return head_dummy.next
1.3 Resumen
El objetivo de esta pregunta es entender qué es una lista enlazada. Es diferente de la lista, la longitud no se puede obtener directamente, es el método de almacenamiento de cada nodo que apunta al siguiente nodo. Otro concepto es que el nodo ficticio apunta al nodo principal. La forma de eliminar un nodo es dejar que el nodo al que apunta lo omita.