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
        
相关推荐
北顾笙9801 小时前
day15-数据结构力扣
数据结构·算法·leetcode
人道领域1 小时前
【LeetCode刷题日记:24】两两交换链表
算法·leetcode·链表
北顾笙9801 小时前
day16-数据结构力扣
数据结构·算法·leetcode
wsoz1 小时前
Leetcode子串-day4
c++·算法·leetcode
会编程的土豆2 小时前
【数据结构与算法】二叉树大总结
数据结构·算法·leetcode
y = xⁿ2 小时前
【LeetCode Hot100】动态规划:T70:爬楼梯 T118:杨辉三角形 T198:打家劫舍
算法·leetcode·动态规划
人道领域2 小时前
【LeetCode 刷题日】19.删除链表的倒数第n个节点
算法·leetcode·链表
py有趣2 小时前
力扣热门100题之最大子数组和
算法·leetcode
小肝一下2 小时前
每日两道力扣,day4
c++·算法·leetcode·职场和发展
牧天白衣.3 小时前
力扣215.数组中的第K个最大元素
算法·leetcode