LeetCode - 19.删除链表的倒数第N个结点

目录

题目

解法一

双指针算法

核心思想

执行流程

具体例子

代码

解法二

两次遍历法

核心思想

执行流程

具体例子

代码


题目

19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode)

解法一

双指针算法

核心思想

利用双指针间隔固定距离(n+1),当快指针到达链表末尾时,慢指针恰好位于倒数第n个节点的前一位置。

执行流程

  1. 创建哑节点dummy,指向链表头部
  2. 初始化快指针fast和慢指针slow,都指向dummy
  3. fast先前进n+1步
  4. fast和slow同时前进,直到fast到达NULL
  5. slow此时指向待删除节点的前一节点,执行删除操作
  6. 返回dummy->next作为新的头节点

具体例子

对于链表1→2→3→4→5,删除倒数第2个节点(n=2):

  1. 创建dummy→1→2→3→4→5
  2. fast和slow初始都指向dummy
  3. fast前进3步(n+1):fast指向3
  4. fast和slow同时前进:
  5. 当fast到达5后的NULL
  6. slow指向3
  7. 删除slow->next(即4):3→5
  8. 返回dummy->next:1→2→3→5

代码

cpp 复制代码
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummy = new ListNode(0);
        dummy->next = head;

        ListNode* fast = dummy;
        ListNode* slow = dummy;

        for(int i = 0; i<n+1; i++)
        {
            if(!fast)
            {
                return head;
            }
            fast = fast->next;
        }

        while(fast)
        {
            fast = fast->next;
            slow = slow->next;
        }

        if(slow->next)
        {
        ListNode* toDelete = slow->next;
        slow->next = slow->next->next;

        delete toDelete;
        }

        ListNode* newhead = dummy->next;
        delete dummy;
        return newhead;
    }
};

解法二

两次遍历法

核心思想

执行流程

  1. 创建哑节点dummy,指向链表头部
  2. 第一次遍历计算链表长度length
  3. 计算待删除节点的正序位置:position = length - n
  4. 第二次遍历,前进position步找到待删除节点的前驱
  5. 删除目标节点
  6. 返回dummy->next作为新的头节点

具体例子

对于链表1→2→3→4→5,删除倒数第2个节点(n=2):

  1. 创建dummy→1→2→3→4→5
  2. 计算链表长度length = 5
  3. 找到正序位置:position = 5 - 2 = 3
  4. 从dummy开始前进3步到达节点3
  5. 删除节点3的下一个节点(4):3→5
  6. 返回dummy->next:1→2→3→5

双指针法效率更高,因为只需一次遍历;两次遍历法思路更直观,易于理解。

代码

cpp 复制代码
ListNode* removeNthFromEnd(ListNode* head, int n) {
    // 创建哑节点
    ListNode* dummy = new ListNode(0);
    dummy->next = head;
    
    // 第一次遍历计算链表长度
    int length = 0;
    ListNode* first = head;
    while (first) {
        length++;
        first = first->next;
    }
    
    // 计算要删除节点的位置
    int position = length - n;
    
    // 找到待删除节点的前一个节点
    ListNode* curr = dummy;
    for (int i = 0; i < position; i++) {
        curr = curr->next;
    }
    
    // 删除节点并释放内存
    ListNode* toDelete = curr->next;
    curr->next = curr->next->next;
    delete toDelete;
    
    // 获取新的头节点
    head = dummy->next;
    delete dummy;
    
    return head;
}
相关推荐
超级码力6666 小时前
【Latex文件架构】Latex文件架构模板
算法·数学建模·信息可视化
穿条秋裤到处跑7 小时前
每日一道leetcode(2026.04.29):二维网格图中探测环
算法·leetcode·职场和发展
Merlos_wind7 小时前
HashMap详解
算法·哈希算法·散列表
汉克老师8 小时前
GESP2025年3月认证C++五级( 第三部分编程题(1、平均分配))
c++·算法·贪心算法·排序·gesp5级·gesp五级
Yzzz-F10 小时前
Problem - 2205D - Codeforces
算法
智者知已应修善业11 小时前
【51单片机2个按键控制流水灯运行与暂停】2023-9-6
c++·经验分享·笔记·算法·51单片机
Halo_tjn11 小时前
Java Set集合相关知识点
java·开发语言·算法
生成论实验室11 小时前
《事件关系阴阳博弈动力学:识势应势之道》第四篇:降U动力学——认知确定度的自驱演化
人工智能·科技·神经网络·算法·架构
AI科技星12 小时前
全域数学·72分册:场计算机卷【乖乖数学】
算法·机器学习·数学建模·数据挖掘·量子计算
科研前沿12 小时前
镜像孪生VS视频孪生核心技术产品核心优势
大数据·人工智能·算法·重构·空间计算