返回

魅力链表,巧用指针——剖析 LeetCode 19 题的快慢指针解法

前端

走近链表与双指针,一览 LeetCode 19 题的快慢指针解法

纵览链表

链表是一种常见的数据结构,由一系列结点组成,每个结点包含一个值和指向下一个结点的指针。链表具有以下特点:

  • 结点可以动态分配和释放,因此链表可以动态地增长和缩短。
  • 链表中的结点可以随机访问,但只能通过指针来访问。
  • 链表的插入和删除操作非常高效,因为不需要移动大量数据。

邂逅双指针

双指针技术是一种常见的算法技巧,常用于解决链表问题。双指针技术的基本思想是使用两个指针同时遍历链表,并根据这两个指针之间的距离来实现不同的功能。

在 LeetCode 19 题中,我们可以使用双指针技术来找到倒数第 n 个结点。具体步骤如下:

  1. 初始化两个指针,slow 和 fast,都指向链表的头结点。
  2. 将 fast 指针向前移动 n 步。
  3. 当 fast 指针到达链表末尾时,slow 指针将指向倒数第 n 个结点。
  4. 将 slow 指针指向 slow 指针的下一个结点,并删除该结点。
  5. 返回链表的头结点。

巧用优先处理

在 LeetCode 19 题中,我们可以通过不同的优先处理方式来优化解法。

  • 优先处理链表长度: 如果我们知道链表的长度,那么我们可以直接将 fast 指针移动到链表的倒数第 (n+1) 个结点,这样就可以避免遍历整个链表。
  • 优先处理特殊情况: 如果要删除的是链表的头结点,那么我们可以直接返回头结点的下一个结点。

代码实现

def remove_nth_from_end(head, n):
  """
  删除链表倒数第 n 个结点。

  参数:
    head:链表的头结点。
    n:要删除的结点在链表中的位置,从链表尾部开始计数。

  返回值:
    链表的头结点。
  """

  # 如果要删除的是链表的头结点,直接返回头结点的下一个结点。
  if n == 0:
    return head.next

  # 否则,使用双指针技术找到倒数第 n 个结点。
  slow = head
  fast = head
  for _ in range(n):
    fast = fast.next

  # 当 fast 指针到达链表末尾时,slow 指针将指向倒数第 n 个结点。
  while fast:
    slow = slow.next
    fast = fast.next

  # 将 slow 指针指向 slow 指针的下一个结点,并删除该结点。
  slow.next = slow.next.next

  # 返回链表的头结点。
  return head

结语

LeetCode 19 题是链表题目中的经典之作,考察了对链表和双指针的理解。通过这道题目的讲解,希望你能对链表和双指针技术有更深入的认识。同时,也希望你能举一反三,将这些技术应用到其他算法问题中。