返回
剖析LeetCode:巧用双指针法删除链表倒数第N个节点(每日计划)
闲谈
2023-09-14 17:56:33
删除链表的倒数第N个节点:巧妙的双指针法
什么是双指针法?
删除链表的倒数第N个节点时,双指针法是一种巧妙且高效的方法。该方法的核心思想是使用两个指针,一个指针(称为“快指针”)先移动N步,然后另一个指针(称为“慢指针”)开始移动。当快指针到达链表尾部时,慢指针刚好位于要删除节点的前一个节点。
双指针法的具体步骤
- 初始化两个指针,fast_ptr和slow_ptr,均指向链表头结点。
- fast_ptr先移动N步,以确保它始终比slow_ptr领先N步。
- 当fast_ptr到达链表尾部时,slow_ptr刚好位于要删除节点的前一个节点。
- 删除slow_ptr的下一个节点(即要删除的节点)。
- 返回删除后的链表头结点。
一个示例
假设我们有一个链表:[1, 2, 3, 4, 5],并且我们要删除倒数第2个节点。
按照双指针法,我们可以这样操作:
- 首先,我们将fast_ptr和slow_ptr都指向链表头结点1。
- 然后,fast_ptr先移动2步,到达节点3。
- 此时,slow_ptr仍然位于节点1,因为fast_ptr比slow_ptr领先2步。
- 当fast_ptr到达链表尾部5时,slow_ptr刚好位于节点3的前一个节点2。
- 因此,我们要删除节点3。我们只需要将slow_ptr的下一个节点(即节点3)指向节点3的下一个节点(即节点4)即可。
- 删除节点3后,链表变为:[1, 2, 4, 5]。
- 最后,我们将删除后的链表头结点1返回。
代码实现
def removeNthFromEnd(head: ListNode, n: int) -> ListNode:
"""
删除链表的倒数第 n 个节点
:param head: 链表头结点
:param n: 要删除的倒数第 n 个节点
:return: 返回删除后的链表头结点
"""
# 创建两个指针:快指针和慢指针
fast_ptr = head
slow_ptr = head
# 快指针先移动 n 步
for _ in range(n):
if fast_ptr is None:
return head.next # 如果快指针到达链表尾部,则删除头节点
fast_ptr = fast_ptr.next
# 当快指针到达链表尾部时,慢指针刚好位于要删除节点的前一个节点
while fast_ptr is not None:
fast_ptr = fast_ptr.next
slow_ptr = slow_ptr.next
# 删除慢指针的下一个节点
slow_ptr.next = slow_ptr.next.next
return head
结论
双指针法是一种删除链表的倒数第N个节点的巧妙算法。它通过使用两个指针,确保慢指针始终位于要删除节点的前一个节点,从而实现高效删除。
常见问题解答
- 为什么要使用双指针法?
双指针法通过同时移动两个指针,确保慢指针始终位于要删除节点的前一个节点,从而实现高效删除,而不需要遍历整个链表。 - 双指针法是如何工作的?
快指针先移动N步,然后慢指针开始移动。当快指针到达链表尾部时,慢指针刚好位于要删除节点的前一个节点。 - 双指针法的复杂度是多少?
双指针法的复杂度为O(n),其中n是链表的长度。 - 双指针法有哪些其他应用?
双指针法还可以用于解决其他链表问题,例如查找链表中点、判断链表是否有环等。 - 除了双指针法,还有哪些删除链表节点的方法?
除了双指针法,还可以使用其他方法删除链表节点,例如:- 递归法
- 迭代法
- 哨兵节点法