November 15, 2024
This problem was tricky as I had to track Node references rather than the index given in the input.
1from collections import defaultdict2"""3# Definition for a Node.4class Node:5 def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):6 self.val = int(x)7 self.next = next8 self.random = random9"""1011class Solution:12 def copyRandomList(self, head: 'Optional[Node]') -> 'Optional[Node]':13 start = Node(head.val) if head else None14 node = start15 randoms = defaultdict(list)16 nodes = {}17 while head:18 nodes[head] = node19 node.next = Node(head.next.val) if head.next else None20 node.val = head.val21 if head.random:22 randoms[head.random].append(head)23 head = head.next24 node = node.next2526 for val in randoms.keys():27 for neighbor in randoms[val]:28 nodes[neighbor].random = nodes[val]2930 return start
O(n) = n since worst case is 2n due to the while loop, then at most visiting each node again when assigning the randoms' value.