Clone list with random pointers
Company: Meta
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: Medium
Interview Round: Technical Screen
Quick Answer: Meta software-engineer technical-screen coding question: deep-copy a singly linked list whose nodes carry an arbitrary random pointer (which may be null, point backward, or form cycles). It tests both the O(n)-space hash-map solution and the O(1)-auxiliary-space in-place weaving technique, plus reasoning about pointer integrity, cycle safety, and verifying the copy is structurally equal to and isolated from the original.
Constraints
- 0 <= number of nodes <= 1000
- -10000 <= node value <= 10000
- random_index is either null (no random pointer) or a valid 0-based index into the list
- random pointers may point backward, forward, to the same node (self), or form cycles
- The returned copy must be fully isolated: no copied node's next/random may reference an original node
Examples
Input: ([[7, None], [13, 0], [11, 4], [10, 2], [1, 0]],)
Expected Output: [[7, None], [13, 0], [11, 4], [10, 2], [1, 0]]
Explanation: Canonical LeetCode-138 example: 5 nodes with assorted backward/forward random links. The deep copy must serialize to the identical array, proving every next and random link was reproduced among the new nodes.
Input: ([[1, 1], [2, 1]],)
Expected Output: [[1, 1], [2, 1]]
Explanation: Two nodes where both random pointers target node 1. Tests that multiple originals can share a random target and the copy preserves that aliasing among clones.
Input: ([[3, None], [3, 0], [3, None]],)
Expected Output: [[3, None], [3, 0], [3, None]]
Explanation: Duplicate values (all 3) with a mix of null and non-null randoms. Identity-keyed cloning must not be confused by equal values; only the middle node has a random link.
Input: ([],)
Expected Output: []
Explanation: Empty list corner case — returns an empty result, exercising the head-is-null early exit.
Input: ([[5, 0]],)
Expected Output: [[5, 0]]
Explanation: Single node whose random points to itself (index 0). The clone's random must point to the clone itself, not the original, and must serialize back to index 0.
Input: ([[1, None]],)
Expected Output: [[1, None]]
Explanation: Single node with a null random — degenerates to copying an ordinary one-element list.
Input: ([[-7, 2], [9, 0], [0, 1], [4, None]],)
Expected Output: [[-7, 2], [9, 0], [0, 1], [4, None]]
Explanation: Negative and zero values with random links forming a small cycle among nodes 0->2->1->0, plus a tail with null random. Confirms cycles in the random graph are handled without infinite loops.
Hints
- First pass: create a clone for every original node and store the mapping original-node -> clone in a hash map. Second pass: for each original node, set clone.next = map[orig.next] and clone.random = map[orig.random], letting null map to null.
- Never *follow* a random pointer while constructing the copy — only look it up in the map. That is exactly why random cycles or self-references can never cause an infinite loop or a double-clone.
- For O(1) auxiliary space, weave each clone directly after its original (A -> A' -> B -> B' -> ...). Then clone.random is simply orig.random.next, and a final unweaving pass restores the original list and extracts the copy.
- Watch the corner cases: an empty list returns an empty result, and a single node whose random points to itself must serialize with random_index 0.