Skip to content

Copy Random List

LeetCode Problem

# https://leetcode.com/problems/copy-list-with-random-pointer/description/
"""
# 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

Every node ALSO has a random pointer (could be pointing anywhere (null, random node etc..))
Deep copy (clone the nodes) : new memory (create new LL)
5 nodes in inp -> 5 nodes in op
  Difficulty : random pointers
  Cloning nodes : [1,2,3]
    3rd node random ptr -> 5th node but we haven't gotten to that node yet : 2 passes/loops
    1st pass : take input node and create deep copy of all nodes (no links)
      also going to create a hashmap (original node -> new node) old node to new copy map
    2nd pass : link the nodes (next and random pointers) [leverage hashmap to get to map every old node to new node] hm : 3->5 so in our copy also copy3 -> copy5

# Time : O(n), Space : O(n)
"""


class Solution:
    def copyRandomList(self, head: "Optional[Node]") -> "Optional[Node]":
        old_to_copy = {None: None}  # for null edge cases

        # first pass : cloning LL nodes and adding to HM
        curr = head
        while curr:  # till end of list
            copy = Node(curr.val)
            old_to_copy[curr] = copy
            curr = curr.next
        # second pass : link pointers
        curr = head
        while curr:
            copy = old_to_copy[curr]  # gives copy node of current
            # set ptrs (next and random)
            copy.next = old_to_copy[
                curr.next
            ]  # except 1 case : current.next = null (handled)
            copy.random = old_to_copy[curr.random]
            curr = curr.next

        # return head of copy
        head_copy = old_to_copy[head]
        return head_copy