【LeetCode刷题】删除链表的倒数第N个结点

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

示例 1:

复制代码
输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

示例 2:

复制代码
输入:head = [1], n = 1
输出:[]

示例 3:

复制代码
输入:head = [1,2], n = 1
输出:[1]

提示:

  • 链表中结点的数目为 sz
  • 1 <= sz <= 30
  • 0 <= Node.val <= 100
  • 1 <= n <= sz

解法思路

  1. 虚拟头节点 :创建dummy节点指向原链表头,避免删除头节点时的特殊处理(如输入head=[1], n=1的情况)。
  2. 双指针初始化fastslow都从dummy开始。
  3. 快指针先行 :让fast先向前走n步,拉开与slow的距离。
  4. 同步移动指针fastslow同时前进,直到fast到达链表末尾(fast.nextNone)。此时slow的下一个节点,就是链表的倒数第 N 个节点
  5. 删除节点 :将slow.next指向slow.next.next,完成节点删除。

核心优势

  • 时间复杂度 O (L):仅遍历链表一次(L 为链表长度),比 "先统计长度再删除" 的两次遍历更高效。
  • 边界全覆盖:通过虚拟头节点,完美处理 "删除头节点""链表长度为 1" 等特殊情况。

Python代码

python 复制代码
# 导入必要的类型注解模块
from typing import Optional


# 完整定义单链表节点类
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

    # 可选:添加打印链表的辅助方法(方便测试)
    def __str__(self):
        result = []
        current = self
        while current:
            result.append(str(current.val))
            current = current.next
        return " -> ".join(result)


# 核心解题类
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        # 虚拟头节点:避免删除头节点时的边界处理
        dummy = ListNode(0)
        dummy.next = head
        fast = dummy
        slow = dummy

        # 步骤1:快指针先向前走n步
        for _ in range(n):
            fast = fast.next

        # 步骤2:快慢指针同时前进,直到快指针到达链表末尾
        while fast.next:
            fast = fast.next
            slow = slow.next

        # 步骤3:删除慢指针的下一个节点(倒数第n个节点)
        slow.next = slow.next.next

        # 返回新的头节点(虚拟头节点的下一个)
        return dummy.next


# 辅助函数:将列表转换为链表(方便测试)
def list_to_linkedlist(arr):
    if not arr:
        return None
    head = ListNode(arr[0])
    current = head
    for val in arr[1:]:
        current.next = ListNode(val)
        current = current.next
    return head


# 测试用例
if __name__ == "__main__":
    # 测试用例1:常规情况
    arr1 = [1, 2, 3, 4, 5]
    n1 = 2
    head1 = list_to_linkedlist(arr1)
    print("原链表1:", head1)
    solution = Solution()
    new_head1 = solution.removeNthFromEnd(head1, n1)
    print(f"删除倒数第{n1}个节点后:", new_head1)  # 预期输出:1 -> 2 -> 3 -> 5

    # 测试用例2:删除头节点
    arr2 = [1, 2]
    n2 = 2
    head2 = list_to_linkedlist(arr2)
    print("\n原链表2:", head2)
    new_head2 = solution.removeNthFromEnd(head2, n2)
    print(f"删除倒数第{n2}个节点后:", new_head2)  # 预期输出:2

    # 测试用例3:链表只有一个节点
    arr3 = [1]
    n3 = 1
    head3 = list_to_linkedlist(arr3)
    print("\n原链表3:", head3)
    new_head3 = solution.removeNthFromEnd(head3, n3)
    print(f"删除倒数第{n3}个节点后:", new_head3)  # 预期输出:None

LeetCode提交代码

python 复制代码
# 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: Optional[ListNode], n: int) -> Optional[ListNode]:
        # 虚拟头节点:避免删除头节点时的边界处理
        dummy = ListNode(0)
        dummy.next = head
        fast = dummy
        slow = dummy
        
        # 步骤1:快指针先向前走n步
        for _ in range(n):
            fast = fast.next
        
        # 步骤2:快慢指针同时前进,直到快指针到达链表末尾
        while fast.next:
            fast = fast.next
            slow = slow.next
        
        # 步骤3:删除慢指针的下一个节点
        slow.next = slow.next.next
        
        # 返回新的头节点(虚拟头节点的下一个)
        return dummy.next

程序运行结果展示

原链表1: 1 -> 2 -> 3 -> 4 -> 5

删除倒数第2个节点后: 1 -> 2 -> 3 -> 5

原链表2: 1 -> 2

删除倒数第2个节点后: 2

原链表3: 1

删除倒数第1个节点后: None

总结

本文介绍了一种高效删除链表倒数第N个节点的双指针解法。通过创建虚拟头节点处理边界情况,使用快慢指针实现一次遍历:快指针先走N步,然后两指针同步移动直至链表末尾,此时慢指针的下一个节点即为待删除节点。该方法时间复杂度O(L)(L为链表长度),优于两次遍历的解法,且能完美处理删除头节点等特殊情况。文中提供了Python实现代码,包含链表转换、测试用例及运行结果验证,确保算法正确性和鲁棒性。该解法已通过LeetCode测试,适用于所有合法输入情况。

相关推荐
O丶ne丨柒夜5 分钟前
Claude Code、Codex 常用命令和命令速查
python
AI科技星6 分钟前
光速螺旋量子几何统一场论:基于四维类时螺旋的物理现象统一推导
开发语言·线性代数·算法·数学建模·平面
weixin_408099676 分钟前
身份证正反面合并+识别OCR接口调用
java·人工智能·后端·python·ocr·api·身份证ocr
We་ct8 分钟前
LeetCode 191. 位1的个数:两种解法详解
前端·算法·leetcode·typescript
vx_biyesheji00018 分钟前
计算机毕业设计:Python汽车市场智能决策系统 Flask框架 可视化 机器学习 AI 大模型 大数据(建议收藏)✅
大数据·人工智能·python·算法·django·汽车·课程设计
2501_920627618 分钟前
Flutter 框架跨平台鸿蒙开发 - 编程代码库应用
学习·算法·flutter·华为·harmonyos
每天回答3个问题9 分钟前
掌握常见的容器的用法
算法·深度优先
源码之家9 分钟前
计算机毕业设计:Python汽车销量智能可视化与预测系统 Flask框架 可视化 机器学习 AI 大模型 大数据(建议收藏)✅
大数据·人工智能·python·机器学习·信息可视化·汽车·课程设计
Dfreedom.10 分钟前
神经网络算法全景解析
人工智能·神经网络·算法
财经资讯数据_灵砚智能14 分钟前
基于全球经济类多源新闻的NLP情感分析与数据可视化(夜间-次晨)2026年4月2日
大数据·人工智能·python·信息可视化·语言模型·自然语言处理·ai编程