"""
# Definition for a Node.
class Node:
def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
self.val = int(x)
self.next = next
self.random = random
"""
class Solution:
def copyRandomList(self, head: 'Optional[Node]') -> 'Optional[Node]':
# # 方法1: 用Hash表存起来 时间复杂度,空间复杂度均为O(n)
# if head == None:
# return None
# dic = {}
# cur = head
# # 构建字典{key: value} 即{原链表: 新链表}
# while cur:
# dic[cur] = Node(cur.val)
# cur = cur.next
# cur = head
# # 构建新链表的next和random
# while cur:
# # 注意!!!!!!!!!!!!!!
# # dic[cur].next = dic[cur.next]
# # 不能按上面的写,因为cur.next不一定在字典里面,它有可能是None
# # 所以要写dic.get(cur.next),也就是从字典里面去查找cur.next对应的值
# # 如果不存在cur.next这个键,则返回的值就是None
# dic[cur].next = dic.get(cur.next)
# # dic[cur].random = dic[cur.random]
# dic[cur].random = dic.get(cur.random)
# cur = cur.next
# return dic[head]
# # 方法2:先拼接再拆分
# if head == None:
# return head
# # 1. 复制各个节点,构建拼接链表
# old = head
# while old:
# new =Node(old.val)
# new.next = old.next
# old.next = new
# old = new.next
# # 2. 构建各个新节点的random指向
# # 三遍遍历列表,时间复杂度O(n), 空间复杂度为O(1)
# old = head
# while old:
# # 如果old.random != None
# if old.random:
# old.next.random = old.random.next
# old = old.next.next
# # 拆开
# old = head
# new = head.next
# ans = new
# # while old and new.next:
# while new.next:
# old.next = old.next.next
# old = old.next
# new.next = new.next.next
# new = new.next
# return ans
# # 方法3:递归+Hash表
# """
# 使用哈希表来缓存已经复制过的节点
# """
# if not head:
# return None
# # 初始化哈希表,用于保存原节点与复制节点之间的映射关系
# cache = {}
# curr = head
# while curr:
# # 如果当前节点已经在哈希表中,则直接使用复制过的节点
# if curr not in cache:
# cache[curr] = Node(curr.val)
# # 复制下一个节点
# cache[curr].next = self.copyRandomList(curr.next)
# # 复制随机指向的节点
# cache[curr].random = self.copyRandomList(curr.random)
# curr = curr.next
# # 由于我们是在原链表上进行遍历,并且复制节点时已经更新了next和random指针
# # 因此可以直接返回头节点的复制节点
# return cache[head]
# 在这个Python代码中,我们定义了一个名为 Solution 的类,其中包含了 copyRandomList 方法,用于复制一个特殊链表。特殊链表的定义是 Node 类,其中包含一个整数值 val,以及指向下一个节点的指针 next 和一个指向任意节点的指针 random。
# copyRandomList 方法首先检查输入的链表头节点 head 是否为 None,如果是,则返回 None,表示链表为空。然后初始化一个字典 cache 来存储原节点与复制节点之间的映射关系。
# 接着,我们使用一个循环遍历原链表,对于每个节点,如果它不在 cache 中,则创建一个新的 Node 实例,并将其添加到 cache 中。然后递归地复制当前节点的 next 和 random 指针。
# 最后,返回 cache[head],即原链表头节点的复制节点。
# 请注意,Python中的递归深度是有限制的,如果链表非常长,可能会导致递归深度超出限制。在实际应用中,可以考虑使用迭代的方法来避免这个问题。
# 同方法1
if not head:
return None
# 创建一个映射表,保存原节点和复制节点的对应关系
mapping = {}
curr = head
# 第一次遍历,复制每个节点
while curr:
mapping[curr] = Node(curr.val)
curr = curr.next
curr = head
# 第二次遍历,设置复制节点的next和random指针
while curr:
mapping[curr].next = mapping.get(curr.next, None)
mapping[curr].random = mapping.get(curr.random, None)
curr = curr.next
return mapping[head]
138. 随机链表的复制
最新推荐文章于 2024-10-04 22:28:47 发布