返回

突破 LeetCode 19:巧解删除链表倒数第 N 个节点的奥秘

后端

引子

在数据结构和算法的世界中,链表是一种广泛使用的数据结构。它由一系列节点组成,每个节点包含一个值和指向下一个节点的指针。LeetCode 19 是一道经典的链表问题,它挑战我们删除链表中倒数第 N 个节点。

解题思路

解决 LeetCode 19 的关键在于找到倒数第 N 个节点并将其从链表中删除。我们可以使用双指针技术来实现这一点。

双指针技术

我们从链表的头节点开始,并使用两个指针:slowfast。我们首先将 fast 指针向前移动 N 步,如果 fast 指针为 null,则意味着链表中没有足够节点来删除倒数第 N 个节点。在这种情况下,我们只需返回链表的头节点。

否则,我们将 slowfast 指针同时向前移动一步,直到 fast 指针到达链表的末尾。此时,slow 指针将指向倒数第 N 个节点的前一个节点。

删除节点

找到倒数第 N 个节点后,我们可以使用 slow 指针来删除它。我们只需要将 slow 指针的 next 指针指向倒数第 N 个节点的下一个节点即可。

代码示例

def remove_nth_from_end(head, n):
    if not head:
        return None

    fast = head
    for _ in range(n):
        fast = fast.next

    if not fast:
        return head.next

    slow = head
    while fast.next:
        fast = fast.next
        slow = slow.next

    slow.next = slow.next.next

    return head

反转技术(可选)

为了进一步优化空间复杂度,我们可以使用反转技术。首先,我们将链表反转,然后删除倒数第 N 个节点,最后再将链表恢复到原来的顺序。

代码示例(反转技术)

def remove_nth_from_end(head, n):
    if not head:
        return None

    # 反转链表
    prev = None
    current = head
    while current:
        next_node = current.next
        current.next = prev
        prev = current
        current = next_node

    # 删除倒数第 N 个节点
    dummy = ListNode(0)
    dummy.next = prev
    slow = dummy
    for _ in range(n):
        slow = slow.next

    slow.next = slow.next.next

    # 恢复链表的顺序
    current = prev
    prev = None
    while current:
        next_node = current.next
        current.next = prev
        prev = current
        current = next_node

    return dummy.next

结语

解决 LeetCode 19 的关键在于巧妙地使用双指针技术或反转技术。通过这些技术,我们可以有效地删除链表中的倒数第 N 个节点,同时保持代码简洁和易于理解。掌握这些技术将大大提升我们在解决其他链表问题时的能力。