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;
}
相关推荐
一匹电信狗2 小时前
【LeetCode_547_990】并查集的应用——省份数量 + 等式方程的可满足性
c++·算法·leetcode·职场和发展·stl
鱼跃鹰飞3 小时前
Leetcode会员尊享100题:270.最接近的二叉树值
数据结构·算法·leetcode
梵刹古音4 小时前
【C语言】 函数基础与定义
c语言·开发语言·算法
筵陌4 小时前
算法:模拟
算法
We་ct5 小时前
LeetCode 205. 同构字符串:解题思路+代码优化全解析
前端·算法·leetcode·typescript
renhongxia15 小时前
AI算法实战:逻辑回归在风控场景中的应用
人工智能·深度学习·算法·机器学习·信息可视化·语言模型·逻辑回归
CoderCodingNo5 小时前
【GESP】C++四级/五级练习题 luogu-P1223 排队接水
开发语言·c++·算法
民乐团扒谱机5 小时前
【AI笔记】精密光时频传递技术核心内容总结
人工智能·算法·光学频率梳
CoderCodingNo5 小时前
【GESP】C++五级/四级练习题 luogu-P1413 坚果保龄球
开发语言·c++·算法
2301_822366356 小时前
C++中的命令模式变体
开发语言·c++·算法