返回
一招解决:删除链表倒数第 N 个结点
前端
2024-01-16 03:52:30
在数据结构的世界中,链表是一种线性的数据结构,其中每个结点包含一个值和指向下一个结点的指针。链表经常用于各种应用中,例如存储数据、实现队列或栈,甚至是模拟文件系统。
有时候,我们可能会需要从链表中删除特定的结点,例如删除链表的倒数第 N 个结点。这个任务可能看起来有些棘手,尤其是当我们希望仅使用一次遍历来完成它的时候。
一网打尽:一次遍历解决问题
要一次性解决这个问题,我们可以采用以下步骤:
- 创建一个虚拟头结点,将其指向链表的第一个结点。这个虚拟头结点将帮助我们简化边界条件的处理。
- 使用两个指针,
pre
和cur
,分别指向虚拟头结点和链表的第一个结点。 - 让
cur
指针向前移动n
步,从而与要删除的结点保持n
个结点的距离。 - 当
cur
指针到达链表的末尾时,pre
指针将指向要删除结点的前一个结点。 - 更新
pre
指针的next
指针,使其指向要删除结点的下一个结点,从而有效地从链表中删除了该结点。
代码实现:
def remove_nth_from_end(head, n):
"""
删除链表的倒数第 n 个结点
Args:
head: 链表头结点
n: 要删除的结点距离链表末尾的距离
Returns:
删除结点后的链表头结点
"""
# 创建虚拟头结点
dummy = ListNode(0, head)
# 初始化 pre 和 cur 指针
pre = dummy
cur = head
# 让 cur 指针向前移动 n 步
for _ in range(n):
cur = cur.next
# 当 cur 指针到达链表末尾时,pre 指针指向要删除结点的前一个结点
while cur:
pre = pre.next
cur = cur.next
# 删除结点
pre.next = pre.next.next
# 返回虚拟头结点的下一个结点,即链表的新头结点
return dummy.next
举例说明
假设我们有一个链表 1 -> 2 -> 3 -> 4 -> 5
,我们需要删除倒数第二个结点(n = 2
)。
- 创建虚拟头结点
dummy
,指向链表的第一个结点1
。 - 初始化
pre
和cur
指针,分别指向dummy
和1
。 - 让
cur
指针向前移动n = 2
步,到达结点3
。 - 由于
cur
指针到达了链表末尾,pre
指针现在指向结点2
,即要删除结点3
的前一个结点。 - 删除结点
3
,更新pre.next
指针指向结点4
。 - 返回虚拟头结点
dummy
的下一个结点,即链表的新头结点1
。
结语
通过使用一次遍历,我们可以高效地从链表中删除倒数第 N 个结点。这种技术在各种链表操作中都非常有用,因为它可以帮助我们避免不必要的遍历和内存分配。理解这一技术将极大地提升你在链表编程方面的能力。