Copy Linked List With Random Pointer

4 min read

Copy Linked List with Random Pointer is a classic interview problem that tests a candidate’s ability to manipulate data structures while preserving complex relationships. The task is to create a deep copy of a singly‑linked list where each node contains, besides the usual next pointer, an additional random pointer that may point to any node in the list—or to null. The challenge lies in reproducing both the next and random links without altering the original list and without using extra space proportional to the number of nodes (unless you deliberately choose a method that does). Below we explore the problem in depth, walk through two popular solutions, analyze their complexities, and provide implementation details in multiple languages.


Understanding the Problem

A node in the original list can be defined as:

class Node {
    int val;
    Node next;
    Node random;
}
  • val holds the node’s data.
  • next points to the subsequent node in the list (or null for the tail).
  • random points to any node in the list (including itself) or null.

The goal is to return the head of a new list where each new node mirrors the val of its counterpart and whose next and random pointers replicate the original structure exactly. Importantly, the original list must remain unchanged after the operation.

Why It’s Tricky

If we merely iterate and create new nodes while setting next pointers, we can easily rebuild the linear chain. The difficulty appears when we try to assign random pointers because the target node may not have been created yet, or we may need to locate it efficiently without scanning the entire list each time (which would lead to O(n²) time) That's the part that actually makes a difference..

Two main strategies solve this elegantly:

  1. Hash‑Map (Dictionary) Approach – O(n) time, O(n) extra space.
  2. Interleaving (Weaving) Approach – O(n) time, O(1) extra space (modifies the list temporarily).

Both guarantee a correct deep copy; the choice depends on whether you are allowed to alter the original list temporarily.


Solution 1: Hash‑Map Approach

Idea

While traversing the original list once, we create a copy of each node and store a mapping from the original node to its copy in a hash map. In a second pass, we use this map to set the next and random pointers of each copied node by looking up the corresponding copies of the original nodes’ next and random.

Step‑by‑Step

  1. First Pass – Node Creation

    • Initialize an empty hash map oldToNew.
    • Iterate through the original list with a pointer curr.
    • For each curr, create a new node copy = new Node(curr.val).
    • Store the mapping oldToNew[curr] = copy.
    • Advance curr = curr.next.
  2. Second Pass – Pointer Assignment

    • Iterate again through the original list.
    • For each curr, retrieve its copy copy = oldToNew[curr].
    • Set copy.next = oldToNew.get(curr.next) (handles null automatically).
    • Set copy.random = oldToNew.get(curr.random).
    • Move to the next original node.
  3. Return the head of the copied list, which is oldToNew.get(originalHead) (or null if the input was empty).

Pseudocode

function copyRandomList(head):
    if head == null: return null
    map = new HashMap()
    curr = head
    while curr != null:
        map[curr] = new Node(curr.val)
        curr = curr.next
    curr = head
    while curr != null:
        copy = map[curr]
        copy.next = map.get(curr.next)
        copy.random = map.get(curr.random)
        curr = curr.next
    return map[head]

Complexity

Aspect Detail
Time Complexity O(n) – two linear passes
Space Complexity O(n) – hash map stores n entries
Modifies Input No (original list stays intact)

Implementation Snippets

Python

class Node:
    def __init__(self, val, next=None, random=None):
        self.val = val
        self.next = next
        self.random = random

def copyRandomList(head):
    if not head:
        return None
    old_to_new = {}
    curr = head
    while curr:
        old_to_new[curr] = Node(curr.val)
        curr = curr.Worth adding: next
    curr = head
    while curr:
        copy = old_to_new[curr]
        copy. next = old_to_new.Day to day, get(curr. On the flip side, next)
        copy. random = old_to_new.And get(curr. random)
        curr = curr.

**Java**

```java
class Node {
    int val;
    Node next;
    Node random;
    Node(int val) { this.val = val; }
}

public Node copyRandomList(Node head) {
    if (head == null) return null;
    Map map = new HashMap<>();
    Node curr = head;
    while (curr != null) {
        map.Because of that, put(curr, new Node(curr. val));
        curr = curr.next;
    }
    curr = head;
    while (curr != null) {
        Node copy = map.On top of that, get(curr);
        copy. next = map.get(curr.Consider this: next);
        copy. Day to day, random = map. On top of that, get(curr. Day to day, random);
        curr = curr. next;
    }
    return map.

**C++**

```cpp
struct Node {
    int val;
    Node* next;
    Node* random;
    Node(int x) : val(x), next(nullptr), random(nullptr) {}
};

Node* copyRandomList(Node* head) {
    if (!head) return nullptr;
    unordered_map map;
    Node* curr = head;
    while (curr) {
        map[curr] = new Node(curr->val);
        curr = curr->next;
    }
    curr = head;
    while (curr) {
        Node* copy = map[curr];
        copy->next = map[curr->next];
        copy->random = map[curr->random];
        curr = curr->next;
    }
    return map[head];
}

Not the most exciting part, but easily the most useful.


Solution 2: Interleaving (Weaving) Approach – O(1) Extra Space

Idea

Instead of a hash map, we interleave copied nodes directly after each original node. The list temporarily looks like:

Original1 -> Copy1 -> Original2 -> Copy2 -> Original3 -> Copy3 -> …

Because each copy sits immediately after its original, we can set the random pointer of a copy by accessing original.next (which points to the copy of the original’s random target). This leads to random. After establishing all pointers, we detach the interleaved list to restore the original and extract the copied list.

Step‑by‑Step

  1. Insert Copies
    • Traverse the original list. For each node `orig
Newest Stuff

Fresh from the Writer

On a Similar Note

Other Perspectives

Thank you for reading about Copy Linked List With Random Pointer. We hope the information has been useful. Feel free to contact us if you have any questions. See you next time — don't forget to bookmark!
⌂ Back to Home