leetcode hot100 19.删除链表的倒数第 N 个结点 快慢指针 medium


核心思路:制造"距离差"

要删除倒数第 nnn 个节点,需要找到它的前驱节点(即倒数第 n+1n+1n+1 个)。

  • 让 fast 指针先向前走 n+1n+1n+1 步。此时,fast (指向第n+1个节点)和 slow (指向第一个节点)之间隔了 nnn 个节点。
  • 同时移动 fast 和 slow,直到 fast 指向最后一个节点。此时 slow 恰好指向倒数第 n+1n+1n+1 个节点

这道题不需要创建新链表,所以不是:

python 复制代码
        prehead = ListNode(-1)
        dummy = prehead
	
			... ...

            # 建立新节点并移动指针
            dummy.next = ... ...
            dummy = dummy.next

重组旧链表,只需要新建一个 prehead 节点,指向链表

python 复制代码
        prehead = ListNode(-1)
        prehead.next = head  
        ... ...

		return prehead.next

直接返回head不行吗,为什么要prehead = ListNode(-1)

prehead.next = head 返回prehead.next:
核心原因:头节点也是会被删除的

假设链表是 1, 2,要删除倒数第 2 个(也就是删除 1):

  1. prehead 指向 1。
  2. 经过计算,slow 停在 prehead 上。
  3. 执行 slow.next = slow.next.next(即 prehead.next = 2)。
  4. 此时:head 变量依然指向 1。prehead.next 指向 2。

如果 return head,结果是 1, 2(错误); 如果 return prehead.next,结果是 2(正确)

"哑节点" (Dummy Node) 的作用

  • 防止"丢头":如上所述,处理头节点被删除的情况。、、
  • 空链表保护:当链表被删空时,prehead.next 会正确返回 None,而直接操作 head 可能会导致空指针引用报错

时间复杂度 :O(N)O(N)O(N)

虽然有两个循环(for 和 while),但指针一共只从头走到尾一次。
空间复杂度:O(1)O(1)O(1)

只额外申请了 prehead, fast, slow 这几个引用空间。

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]:

        # 用于指向新链表
        prehead = ListNode(-1)
        prehead.next = head  # 这一步是修复报错的关键

        # 用于操作旧链表
        fast = slow = prehead
        
        # fast先走n+1步
        for i in range(n+1):
            fast = fast.next

        # 同时移动 fast 和 slow,直到 fast 指向最后一个节点
        # 此时 slow 恰好指向倒数第 n+1 个节点
        while fast:
            slow = slow.next
            fast = fast.next

        # 倒数第 n+1 个节点,应该指向:倒数第 n+2 个节点
        #(跳过倒数n)
        tmp = slow.next.next
        slow.next = tmp

        return prehead.next
        
相关推荐
8Qi86 小时前
回文子串(Palindromic Substrings)—— 题解
算法·leetcode·职场和发展·动态规划
小欣加油11 小时前
leetcode1926 迷宫中离入口最近的出口
数据结构·c++·算法·leetcode·职场和发展
兰令水19 小时前
leecodecode【区间DP+树形DP】【2026.6.10打卡-java版本】
java·算法·leetcode
8Qi820 小时前
LeetCode 4:寻找两个正序数组的中位数 —— 二分查找法
java·算法·leetcode·职场和发展·二分查找
8Qi820 小时前
LeetCode 32:最长有效括号 —— 栈 + 标记法 题解
java·数据结构·算法·leetcode·职场和发展··括号匹配
Tairitsu_H20 小时前
[LC优选算法#3] 滑动窗口 | 将x减到0的最⼩操作数 | ⽔果成篮 | 字⺟异位词
c++·算法·leetcode·滑动窗口
洛水水21 小时前
【力扣100题】76.搜索插入位置
数据结构·算法·leetcode
wabs6661 天前
关于动态规划【力扣343.整数拆分的递推公式怎么理解?】
算法·leetcode·动态规划
承渊政道1 天前
【MySQL数据库学习】MySQL基本查询(下)
数据库·学习·mysql·leetcode·bash·数据库开发·数据库系统
洛水水1 天前
【力扣100题】78.在排序数组中查找元素的第一个和最后一个位置
数据结构·算法·leetcode