链表-LeetCode138. 复制带随机指针的链表

1、题目描述

https://leetcode-cn.com/problems/copy-list-with-random-pointer/

给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。要求返回这个链表的 深拷贝。 

我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

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

输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]

2、代码详解

python3版代码

时间复杂度:O(N) 空间复杂度:O(1)

(1)遍历原来的链表并拷贝每一个节点,将拷贝节点放在原来节点的旁边,创造出一个旧节点和新节点交错的链表。

image.png

(2)迭代这个新旧节点交错的链表,并用旧节点的 random 指针去更新对应新节点的 random 指针。比方说, B 的 random 指针指向 A ,意味着 B' 的 random 指针指向 A'

image.png

(3)现在 random 指针已经被赋值给正确的节点, next 指针也需要被正确赋值,以便将新的节点正确链接同时将旧节点重新正确链接。

image.png

"""
# 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: 'Node') -> 'Node':
        if not head:
            return head
        # 1)遍历原来的链表并拷贝每一个节点,将拷贝节点放在原来节点的旁边,创造出一个旧节点和新节点交错的链表
        cur = head
        while cur is not None:
            next = cur.next
            node = Node(cur.val)  # 加入 复制节点,复制结点紧靠原结点
            node.next = cur.next
            cur.next = node
            cur = next  # 原节点 后移
        copy = head.next  # 复制后的头结点

        # 2)迭代这个新旧节点交错的链表,并用旧节点的 random 指针去更新对应新节点的 random 指针
        # 先同步随机结点引用(random 指针 赋值给正确的节点)
        pre = head
        while pre is not None:
            if pre.random:
                pre.next.random = pre.random.next  # B 的 random 指针指向 A ,意味着 B' 的 random 指针指向 A'
            else:
                pre.next.random = None
            pre = pre.next.next
        # 3)next 指针也需要被正确赋值,以便将新的节点正确链接同时,将旧节点重新正确链接。
        # 再还原结点顺序指向
        pre = head
        while pre is not None:
            next = pre.next.next  # B
            if next is not None:
                pre.next.next = next.next  # A' -> B'
            else:
                pre.next.next = None
            pre = next  # A -> B

        return copy

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值