题目:
给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]
1. 删除链表的倒数第 N 个节点;
设置快慢双指针,
-
让快指针先移动 n+1 步骤,
-
同时移动快慢指针;
-
删除 目标节点;
lc19: 删除链表的倒数第N 个节点
class Solution:
def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
dummy = ListNode(val=0,)
dummy.next = head
# 初始化两个节点, 都是从 dummy 开始;
fast = dummy
slow = dummy
# 让fast 先移动n +1 步;
# 使用 n+1 步骤的原因,是后续同时移动时, 停止时, slow 位于目标节点的前一个节点, 从而方便删除;
# 如果 使用 n 步, 则停止时, slow 位于 目标节点位置,不方便删除;
for i in range(n +1):
fast = fast.next
# 然后让 fast, slow 同时移动; 从而 fast领先 slow 有n 个步骤
# 当fast 到达空节点时, slow 节点位于待删除节点的前一个节点;
while fast:
fast = fast.next
slow = slow.next
# 令 slow 节点的下一个节点为 删除节点的下一个节点;
slow.next = slow.next.next
return dummy.next
关键点:
- 理清增加 虚拟头节点前后, 删除节点的 前置节点在哪里
- 找出 增加虚拟节点后, 需要循环几步到达 删除节点的 前置节点;
2. 代码实现
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def removeNthFromEnd(self, head: ListNode, N : int) -> ListNode:
def getLength(head: ListNode) -> int:
length = 0
while head:
head = head.next
length += 1
return length
dummy_head = ListNode(None)
pred = dummy_head
pred.next = head
L = getLength(head)
for _ in range(0, L - N): # 算上虚拟头节点, 一共循环L-N 次;
pred = pred.next
pred.next = pred.next.next # 循环结束后, pred 为 删除节点的前置节点
return dummy_head.next # 返回真正的头节点