Copy List with Random Pointer Solution
Construct a deep copy of a linked list where each node has an additional random pointer to any node or null.
Problem Statement
A linked list of length n is given where each node has an additional random pointer that could point to any node in the list, or null. Construct a deep copy of the list — new nodes with the same value, next, and random structure.
HashMap — O(n) space
Two passes: (1) Create a copy of each node and store old→new mapping in a HashMap. (2) Walk through and assign next and random pointers using the map. The map lets us look up the new copy of any original node in O(1).
The random pointer can point to any node — we can't set it until all copies exist. The HashMap bridges old and new: for any original node, map.get(original) gives its copy.
Interleave & Separate — O(1) extra space
Three passes without a hashmap: (1) Insert a copy of each node right after the original: A→A'→B→B'→... (2) Set random pointers: copy.random = original.random.next. (3) Separate the interleaved list into original and copy.
- Pass 1 — Interleave: For each node A, create A' and insert: A→A'→B→B'→...
- Pass 2 — Random pointers:
A'.random = A.random.next(A.random points to original, .next is its copy). - Pass 3 — Separate: Extract copies: A.next = A'.next, A'.next = (A'.next != null ? A'.next.next : null).
Visual Walkthrough
HashMap approach for list: A(random→C) → B(random→A) → C(random→null):
Code — Java & Python
Complexity Analysis
| Approach | Time | Space | Trade-off |
|---|---|---|---|
| HashMap | O(n) | O(n) | Clean, easy to understand. Map stores old→new. |
| Interleave ← space-optimal | O(n) | O(1) | Three passes, no extra map. Trickier pointer work. |
Edge Cases & Pitfalls
| Case | Input | Why It Matters |
|---|---|---|
| Empty list | null | Return null immediately. |
| Single node, random=self | A→null, A.random=A | Copy's random must point to the copy, not the original. |
| All random=null | Standard list | Degenerates to normal copy — random stays null. |
copy.random = original.random directly (without mapping). This makes the copy's random point to a node in the original list, not the copy — the deep copy is broken.