138. 随机链表的复制

"""
# 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]



        


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值