给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的 深拷贝。
我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:
val:一个表示 Node.val 的整数。
random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。
收获/注意:
1. 本题要求我们返回链表的深拷贝,which means that 返回链表中的每一个节点都是要新建的 new_node = Node(head.val)
2. 回溯法中一个新节点的建立是: 建立 node(head.val) -> 加入字典 hashdict[ head ] = node -> node.next = copyRandomList(head.next) -> node.random = copyRandomList(head.random)
a) 疑问:问题在于 加入字典的node是只有val,后续才补上的next,random,如果在递归期间,该节点被调用了,应该只有val 没有next,ranodm,这个问题是怎么解决的呢?
b)
c) 例如上图中 C.next 得到的D(4,None, A)中的A是 Node(1,None,None) ,这里的A是否会动态变化。
法1) 回溯法(递归) 本题借鉴leetcode官方题解
# 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 __init__(self):
# it is a dict whose keys and values are oldNode and newNode respectively.
self.hashdict = {}
def copyRandomList(self, head: 'Node') -> 'Node':
if head is None:
return None
if head in self.hashdict:
return self.hashdict[head]
else:
node = Node(head.val,None,None)
self.hashdict[head] = node
node.next = self.copyRandomList(head.next)
node.random = self.copyRandomList(head.random)
return node