862 字
4 分钟
4月7日刷题笔记——随机链表复制和删除链表节点

本篇题目#

#138随机链表的复制
Medium
#237删除链表中的节点
Medium

LeetCode 138 · 随机链表的复制#

#138随机链表的复制
Medium

思路#

每个节点除了 next,还有一个 random 指针,可以指向链表中任意节点(或 None)。

难点在于:连接 random 时,目标节点可能还没被创建出来。比如处理节点 A 时,想让新 A 的 random 指向新 C,但新 C 还不存在。

解决方案:分两步走,先造节点,再连线。

第一步:遍历原链表,为每个节点创建对应的新节点,存入哈希表:

dic = { 原A: 新A, 原B: 新B, 原C: 新C }

此时新节点的 nextrandom 都是 None,只是先把所有节点造好。

第二步:再遍历一遍,统一连接 nextrandom。此时所有新节点都已存在,可以放心查字典:

dic[curr].next = dic.get(curr.next) # 原节点的next → 对应的新节点
dic[curr].random = dic.get(curr.random) # 原节点的random → 对应的新节点

为什么 key 是节点对象而不是节点值?

因为节点值可能重复(比如两个节点都是 1),用值做 key 会冲突。节点对象本身在内存中是唯一的,用对象做 key 才能精确对应。

代码#

class Solution:
def copyRandomList(self, head: 'Optional[Node]') -> 'Optional[Node]':
if not head: return
curr = head
dic = {}
# 第一步:造节点,建立"原节点 → 新节点"的映射
while curr:
dic[curr] = Node(curr.val)
curr = curr.next
curr = head
# 第二步:连接 next 和 random
while curr:
dic[curr].next = dic.get(curr.next) # 找到原节点next对应的新节点
dic[curr].random = dic.get(curr.random) # 找到原节点random对应的新节点
curr = curr.next
return dic[head]

关键细节#

dic[curr].next = dic.get(curr.next) 拆解

curr.next → 原B(这是 key)
dic.get(原B) → 新B(这是 value)
dic[curr].next = 新B → 新curr的next指向新B

为什么用 dic.get() 而不是 dic[]

curr.nextcurr.random 可能是 None

  • dic.get(None) → 返回 None,不报错 ✅
  • dic[None] → 抛出 KeyError

常见 bug

# ❌ 错误写法:把 dic[curr] 覆盖掉了,映射关系丢失
dic[curr] = dic.get(curr.next)
dic[curr].random = dic.get(curr.random) # 此时 dic[curr] 已经不是新节点了
# ✅ 正确写法:修改新节点的属性,不动字典本身
dic[curr].next = dic.get(curr.next)
dic[curr].random = dic.get(curr.random)

总结#

  • 核心技巧:哈希表建立”原节点 → 新节点”映射,先批量造节点,再批量连线
  • 复杂度:时间 O(n),空间 O(n)

LeetCode 237 · 删除链表中的节点#

#237删除链表中的节点
Medium

思路#

正常删除节点需要找到前一个节点,然后:

前节点.next = 当前节点.next

但这题只给你当前节点,没给 head,根本找不到前节点。

换个思路:不删自己,把下一个节点的值复制过来,再删下一个节点。

删前: ... → node(3) → next(4) → ...
第一步: ... → node(4) → next(4) → ... # 把值覆盖
第二步: ... → node(4) → next.next → ... # 跳过next

视觉上看起来 node 被删掉了,实际上是”偷梁换柱”。

代码#

class Solution:
def deleteNode(self, node):
node.val = node.next.val # 把下一个节点的值复制到当前节点
node.next = node.next.next # 跳过下一个节点

总结#

  • 核心技巧:无法找前驱时,用”值覆盖 + 跳过下一节点”模拟删除
  • 复杂度:时间 O(1),空间 O(1)

两题横向对比#

题目核心技巧关键限制
138 随机链表的复制哈希表映射,两轮遍历key 必须是节点对象,不能是节点值
237 删除链表中的节点值覆盖 + 跳过下一节点只给当前节点,无法找前驱
4月7日刷题笔记——随机链表复制和删除链表节点
https://www.yyylegend.com/posts/4月7日刷题笔记随机链表复制和删除链表节点/
作者
YYYLEGEND
发布于
2026-04-07
许可协议
CC BY-NC-SA 4.0