Copy with Random Pointer
Each node has a next pointer AND a random pointer to any node. Clone in 3 steps: (1) interleave clones between originals, (2) set random pointers using the interleaving, (3) separate the two lists. O(n) time, O(1) extra space.
How It Works
Deep-copying a list whose nodes carry a random pointer is hard because a random pointer may target a node whose clone does not exist yet. The hash map solution makes two passes — first create all clones keyed by original node, then wire next and random through the map — at O(n) extra space. The interleaving trick removes that space: pass one splices each clone directly after its original, so the list becomes A, A', B, B', ... Pass two sets each clone's random in O(1) as original.random.next, since a clone always sits immediately after its original. Pass three unweaves the two lists, restoring the original and extracting the copy.
All three passes are linear, giving O(n) time with O(1) auxiliary space.
Step-by-Step Visualization
Code
static Node copyRandomList(Node head) {
if (head == null) return null;
Map<Node, Node> map = new HashMap<>();
Node curr = head;
while (curr != null) {
map.put(curr, new Node(curr.val));
curr = curr.next;
}
curr = head;
while (curr != null) {
map.get(curr).next = map.get(curr.next);
map.get(curr).random = map.get(curr.random);
curr = curr.next;
}
return map.get(head);
}Tips & Gotchas
Practice Problems
- 1Copy List with Random Pointer
- 2Clone Graph
- 3Clone Binary Tree With Random Pointer
About the Design Problems Pattern
Build more complex data structures on top of linked lists. These combine linked lists with hash maps for O(1) operations.
Most linked list problems are about pointer manipulation. Draw it out! Fast & slow pointers detect cycles and find midpoints. In-place reversal is the other core technique.
Common Linked List Interview Problems
- Reverse Linked List
- Merge Two Sorted Lists
- Linked List Cycle
- Remove Nth Node From End
- LRU Cache
- Reorder List
Frequently Asked Questions
What makes original.random.next the correct clone lookup?
The interleaving guarantees a positional invariant: every clone is the immediate successor of its original. So following an original's random pointer lands on some original node X, and X.next is by construction X's clone — the map lookup has been encoded into the list's structure itself.
Should I reach for the map version or the interleaving version first?
Lead with the hash map: it is a straightforward O(n) time, O(n) space solution and generalizes to Clone Graph. Offer the interleaving as the O(1)-space refinement, noting its constraints — it temporarily mutates the input and assumes exclusive access to the list.
What is the subtle bug when handling null random pointers?
Writing clone.random = original.random.next without a null check dereferences null whenever original.random is null. Guard it: the clone's random should be null in that case. The same guard applies in the map version when looking up map.get(null).