📜  数据结构 |链表 |问题 15(1)

📅  最后修改于: 2023-12-03 15:26:09.083000             🧑  作者: Mango

题目描述

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.

说明:

给定的 n 保证是有效的。

进阶:

你能尝试使用一趟扫描实现吗?

题目解析

删除链表的倒数第 n 个节点,容易想到快慢指针。

首先让快指针先走 n 步,然后让快指针和慢指针一起走,直到快指针走到链表的末尾。

这时,慢指针所指向的节点即为要删除的节点的前一个节点,我们只需要将其 next 指针指向下下个节点即可删除倒数第 n 个节点。

需要注意的是,如果要删除的是第一个节点,我们需要特判处理,此时直接返回第二个节点即可。

这个问题可以通过使用一次扫描实现。我们可以使用双指针来维护。 image.png

代码实现

class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        # 新建一个虚拟头节点,用来处理删除第一个节点的情况
        dummy = ListNode(0)
        dummy.next = head

        # 初始化快指针与慢指针
        fast = slow = dummy

        # 快指针先走 n 步
        for i in range(n):
            fast = fast.next

        # 快指针和慢指针一起走,直到快指针走到链表的末尾
        while fast and fast.next:
            fast = fast.next
            slow = slow.next

        # 要删除的节点的前一个节点
        prev = slow

        # 删除倒数第 n 个节点
        prev.next = prev.next.next

        # 返回链表的头节点
        return dummy.next

时间复杂度:$O(n)$

空间复杂度:$O(1)$