Copy List With Random Pointer

To solve this coding challenge, we need to create a deep copy of a linked list where each node has a next pointer and a random pointer. This involves creating new nodes such that both the next and random pointers in the copied list point to new nodes in the copied list, maintaining the same structure as the original list. Below is a detailed explanation of how we can achieve this along with pseudocode.

Explanation

  1. Initialization :
    • We need to handle the case where the input list is empty (
      n == 0
      ). If the list is empty, we immediately return
      null
      .
    • For all non-empty lists, we will use a map (or dictionary) to store the mapping between the original nodes and their corresponding new nodes. This allows us to efficiently create a deep copy and set the appropriate pointers.
  2. First Pass :
    • Traverse the original list and create a new node for each original node. During this traversal, populate the map with the original nodes as keys and the newly created nodes as the corresponding values.
  3. Second Pass :
    • Traverse the original list again, this time setting the
      next
      and
      random
      pointers of the newly created nodes using the map. This ensures that the
      next
      and
      random
      pointers in the copied list point to the appropriate new nodes, maintaining the original list structure.
  4. Return the head :
    • Finally, return the new head that is stored as the value in the map corresponding to the original head node.
    This process ensures that we accurately copy both the
    next
    and
    random
    pointers for each node, creating a deep copy of the entire list.

    Pseudocode

                                                
    # Function to copy the list with random pointer
    function copyRandomList(head):
    # Check if the input list is empty
    if head is null:
    return null
    
    # Initialize a map to keep track of original to new node mapping
    node_map = map()
    
    # Pointer to the current node in the original list
    original_node = head
    
    # First pass to create new nodes and populate the map
    while original_node is not null:
    # Create a new node with the same value as the original node
    new_node = new Node(original_node.value)
    
    # Add the original and new node pair to the map
    node_map.set(original_node, new_node)
    
    # Move to the next node in the original list
    original_node = original_node.next
    
    # Reset the pointer to the head of the original list for the second pass
    original_node = head
    
    # Second pass to set the next and random pointers in the new list
    while original_node is not null:
    # Get the corresponding new node from the map
    new_node = node_map.get(original_node)
    
    # Set the next pointer for the new node
    new_node.next = node_map.get(original_node.next) if original_node.next is not null else null
    
    # Set the random pointer for the new node
    new_node.random = node_map.get(original_node.random) if original_node.random is not null else null
    
    # Move to the next node in the original list
    original_node = original_node.next
    
    # Return the new head corresponding to the original head
    return node_map.get(head)
    
                                            

    Detailed Steps in Pseudocode

  5. Check if the input list is empty :
    • If
      head
      is
      null
      , immediately return
      null
      .
  6. Initialize the map :
    • Create an empty map called
      node_map
      to hold the mapping between original nodes and their corresponding new nodes.
  7. First Pass: Create Nodes :
    • Initialize
      original_node
      pointer to
      head
      .
    • Traverse the list using a
      while
      loop:
      • For each node
        original_node
        , create a
        new_node
        with the same
        value
        .
      • Insert
        original_node
        and
        new_node
        into
        node_map
        .
      • Move
        original_node
        to its next node using
        original_node.next
        .
  8. Second Pass: Set Pointers :
    • Reset
      original_node
      to
      head
      again.
    • Traverse the list using a
      while
      loop:
      • For each node
        original_node
        , get
        new_node
        from
        node_map
        .
      • Set
        new_node.next
        to the node mapped from
        original_node.next
        or
        null
        if
        original_node.next
        is
        null
        .
      • Set
        new_node.random
        to the node mapped from
        original_node.random
        or
        null
        if
        original_node.random
        is
        null
        .
      • Move
        original_node
        to its next node.
  9. Return the new head :
    • Return
      node_map.get(head)
      which gives the new head corresponding to the original head.
This method ensures a correct deep copy of the list, including maintaining the correct
random
pointers.