Last Updated: March 29, 2026
On the surface, copying a linked list sounds simple: iterate through the original, create new nodes, wire up next pointers. Done. But the random pointer throws a wrench into that plan. When you're building the copy node by node, the random pointer might reference a node you haven't created yet. You can't set copy.random = original.random because that would point into the original list, not the copy.
So the core challenge is this: how do you map each original node to its corresponding copy so that when it's time to wire up random pointers, you know exactly which copy node to point to?
0 <= n <= 1000 → With n up to 1,000, even O(n^2) would be roughly 1 million operations, well within time limits. But O(n) is clearly preferred.-10^4 <= Node.val <= 10^4 → Values can be negative and can repeat, so you cannot use node values as unique identifiers.Node.random is null or points to some node in the list → Random pointers form arbitrary connections. They're not necessarily forward-pointing, can create cycles, and can point to the node itself.The most natural way to handle the mapping problem is to use a hash map. In the first pass, we create a copy of every node and store the mapping from original to copy. In the second pass, we wire up both next and random pointers using the map to translate original references into copy references.
This is straightforward and hard to get wrong. The hash map acts as a translator: give it any original node, and it hands back the corresponding copy.
head is null, return null.map[original] = copy.map[original].next = map[original.next] and map[original].random = map[original.random].map[head], which is the head of the copied list.The hash map uses O(n) extra space purely to translate original-to-copy references. What if we could encode that mapping within the list structure itself?
Instead of using a hash map, we weave the copy nodes directly into the original list. For each original node A, we insert its copy A' right after it, so the list becomes A -> A' -> B -> B' -> C -> C' -> ...
Now the mapping from original to copy is encoded in the structure itself: original.next is always the copy. For random pointers, if original.random points to some node X, then original.random.next is X's copy. So copy.random = original.random.next. No hash map needed.
After wiring up random pointers, we un-interleave the list to separate the original and copy into two independent lists.
head is null, return null.original.next.random = original.random.next. Handle null random pointers.