Python编程:随机链表的复制

题目:

给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 

例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。+返回复制链表的头节点。用一个由 n 个节点组成的链表来表示输入/输出中的链表。

每个节点用一个 [val, random_index] 表示:

  • val:一个表示 Node.val 的整数。
  • random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为  null 。

你的代码  接受原链表的头节点 head 作为传入参数。

示例:

思路:

本题目文字较长,且内容较多,容易使做题者产生畏难情绪,感觉是在做阅读理解,无从下手。实际上,耐心读完后就会发现题目的要求很容易理解,就是要:创建出一个新链表,并且让这个新链表的所有节点的val、next、random都和原链表完全相同。理解到这里后,思路就比较清晰了,就是要用代码手动实现“复制”的操作。怎么复制、如何复制就是下一个问题。

题目要求创建一个新链表,把原链表的内容都复制到新链表上。首先我们要清楚复制哪些东西,是原链表每个节点的val、next、random。其中,val的复制难度不大,复杂的部分是它们之间的连接关系。因此,我们可以尝试采用哈希表(Python语言里可称为字典)来记录原节点和新复制节点之间的映射关系。这样,在遍历链表并复制节点时,我们可以方便地查找或存储新创建的节点。具体的实现步骤可以为:

1.遍历原链表:为每个节点创建一个新的复制节点,并将新节点插入到原节点之后。同时,将原节点与新节点的映射(复制)关系存储在哈希表中。

2.设置每个新节点的 next 和 random 指针:此时,我们可以利用哈希表来找到对应原节点的复制节点,从而连接指针,实现让 next 和 random 指针正确指向其新节点的效果。

3.将链表拆分为原链表和复制链表:由于每个新节点都紧跟在原节点之后,我们可以通过调整 next 指针来拆分链表,最后将“复制链表”连接到新链表头后,再返回新的头结点。

实现:

完整代码如下:(Python实现)

# 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


def copyRandomList(head):
    if not head:
        return None
    node_map = {}  # 哈希表存储克隆关系
    current = head
    while current:
        clone = Node(current.val)  # 克隆节点
        node_map[current] = clone  # 存储克隆关系
        clone.next = current.next  # 把克隆节点放在原节点后
        current.next = clone
        current = current.next.next

    current = head
    while current:
        if current.random:
            current.next.random = node_map[current.random] 
        current = current.next.next

    h = Node(0)
    new_head = h
    current = head
    while current:  # 尾插法创建链表
        clone = current.next
        current.next = clone.next
        new_head.next = clone
        new_head = new_head.next
        current = current.next

    return h.next


# 示例:构建链表: 1 -> 2 -> 3, random pointers: 1 -> 3, 2 -> 3, 3 -> 1
head = Node(1)
head.next = Node(2)
head.next.next = Node(3)
head.random = head.next.next
head.next.random = head.next.next
head.next.next.random = head
# 复制链表
cloned_head = copyRandomList(head)
# 输出克隆链表(供验证)
while cloned_head:
    print(cloned_head.val, end='->')
    cloned_head = cloned_head.next

题目来源:力扣(Leetcode)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值