返回

解构LeetCode经典谜题,深入浅出掌握链表操作:从零开始彻底攻克19题

后端

图解LeetCode——19. 删除链表的倒数第 N 个结点

一、题目:

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

二、示例:

2.1 示例1:

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

2.2 示例2:

输入:head = [1], n = 1
输出:[]

2.3 示例3:

输入:head = [1,2], n = 1
输出:[1]

三、提示:

  • 链表中结点的数目为 sz
  • 1 <= sz <= 10^5
  • 0 <= Node.val <= 10^5
  • 1 <= n <= sz

四、解题思路:

  1. 确定删除位置:

    • 计算链表长度 len
    • 倒数第 N 个结点位置 = len - N
  2. 双指针法:

    • 使用两个指针 p1 和 p2 同时遍历链表
    • p1 先走 N 步,到达删除位置
    • p2 从头开始走,当 p1 到达删除位置时,p2 刚好到达要删除结点的上一个结点
    • 将 p2 的 next 指向 p1 的 next,即可删除结点
  3. 递归法:

    • 递归地求解删除链表的倒数第 N 个结点的问题
    • 递归函数的参数为头结点和 N
    • 递归函数的返回值为删除结点后的链表的头结点
    • 递归的终止条件为 N == 0,此时返回头结点
    • 在递归函数中,先递归地求解删除链表的倒数第 N - 1 个结点的问题
    • 然后将返回的头结点设为当前结点的 next
    • 返回当前结点

五、代码实现:

# Definition for singly-linked list.
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        # 计算链表长度
        len = 0
        p = head
        while p:
            len += 1
            p = p.next

        # 计算删除位置
        delete_pos = len - n

        # 双指针法删除结点
        p1 = p2 = head
        for _ in range(delete_pos):
            p1 = p1.next

        if p1 == head:
            return head.next

        while p1.next:
            p1 = p1.next
            p2 = p2.next

        p2.next = p1.next

        return head

六、结语:

解开LeetCode 19题的奥秘,不仅让你对链表操作有了更深入的理解,也为你的算法学习之旅增添一抹新的色彩。LeetCode就像是一座亟待攀登的山峰,越过一座座挑战,你会发现自己已经登上了更高的平台,俯瞰更广阔的视野。祝愿你一路披荆斩棘,在算法的海洋里乘风破浪!