Skip to content

Copy List with Random Pointer

A linked list of length n is given such that each node contains an additional random pointer, which could point to any node in the list, or null.

Construct a deep copy of the list. The deep copy should consist of exactly n brand new nodes, where each new node has its value set to the value of its corresponding original node. Both the next and random pointer of the new nodes should point to new nodes in the copy list such that the pointers in the copy list represent the same relationships as the pointers in the original list (based on the nodes in the original list, not on their values).

Return the head of the copied linked list.

InputOutputExplanation
[[7,null],[13,0],[11,4],[10,2],[1,0]]Same structure5-node list; node 13’s random points to node 7 (index 0) in the original, and the copy’s node 13’s random points to the copy’s node 7.
[[1,1],[2,1]]Same structure2-node list; both nodes’ random pointers point to node 1 in both original and copy.
[[3,null]]Same structureSingle node with null random pointer.
  • 0 <= n <= 100
  • -100 <= Node.val <= 100
  • Node.random is null or points to some node in the list.
ApproachTimeSpaceBest When
Hash MapO(n)O(n)Most common; easier to understand and implement
InterweavingO(n)O(1)Space is critical; demonstrates clever pointer manipulation
  • Learn Hash Map first — it is straightforward and widely used in interviews.
  • Use Interweaving as an advanced follow-up to show deeper understanding of pointer mechanics.
Clear & Intuitive
Hash Map
O(n) time · O(n) space
Space-Optimal
Interweaving
O(n) time · O(1) space
★ Recommended

Use a hash map to store the mapping between original nodes and their clones. In the first pass, create all cloned nodes and store them in the map. In the second pass, connect the next and random pointers of the cloned nodes by looking up the original pointers in the map.

The key insight is to separate node creation from pointer assignment, allowing us to reference any node’s clone regardless of traversal order.

⏱ Time O(n) Two passes 💾 Space O(n) Hash map stores n nodes

Input: [[7,null],[13,0],[11,4],[10,2],[1,0]]

Original list: 7 → 13 → 11 → 10 → 1

  • Node 7’s random: null
  • Node 13’s random: 7 (index 0)
  • Node 11’s random: 1 (index 4)
  • Node 10’s random: 11 (index 2)
  • Node 1’s random: 7 (index 0)
StepNodeAction
1Create clonesCreate nodes: 7’, 13’, 11’, 10’, 1’ in hash map
2Node 7 → 13Copy 7.next=13 → 7’.next=13’
3Node 7 → nullCopy 7.random=null → 7’.random=null
4Node 13 → 0Copy 13.random=nodes[0] → 13’.random=nodeMap[nodes[0]]=7’

Animated walkthrough

How the hash map solution clones nodes and their pointers

Use Next or Autoplay to see nodes created in the map, then each original pointer mapped to a cloned pointer.

Step 1 of 3
Waiting to begin...
Array state
Memory / lookup state

function copyRandomList(head):
if head is null:
return null
nodeMap = {}
// First pass: create all nodes
current = head
while current != null:
nodeMap[current] = Node(current.val)
current = current.next
// Second pass: set pointers
current = head
while current != null:
copy = nodeMap[current]
copy.next = nodeMap[current.next] if current.next else null
copy.random = nodeMap[current.random] if current.random else null
current = current.next
return nodeMap[head]
copy_list_with_random_pointer_hash_map.py
from typing import Optional
class Node:
def __init__(self, x: int, next: "Node" = None, random: "Node" = None):
self.val = x
self.next = next
self.random = random
def copyRandomList(head: Optional[Node]) -> Optional[Node]:
if not head:
return None
# Map original nodes to their copies
node_map = {}
# First pass: create all copy nodes
current = head
while current:
node_map[current] = Node(current.val)
current = current.next
# Second pass: set next and random pointers
current = head
while current:
copy_node = node_map[current]
copy_node.next = node_map[current.next] if current.next else None
copy_node.random = node_map[current.random] if current.random else None
current = current.next
return node_map[head]
# Test cases
def print_list(head: Optional[Node]):
result = []
current = head
while current:
result.append((current.val, current.random.val if current.random else None))
current = current.next
return result
# Example 1: [[7,None],[13,0],[11,4],[10,2],[1,0]]
node1 = Node(7)
node2 = Node(13)
node3 = Node(11)
node4 = Node(10)
node5 = Node(1)
node1.next = node2
node2.next = node3
node3.next = node4
node4.next = node5
node1.random = None
node2.random = node1
node3.random = node5
node4.random = node3
node5.random = node1
copy = copyRandomList(node1)
print(print_list(copy)) # [(7, None), (13, 7), (11, 1), (10, 11), (1, 7)]
# Example 2: [[1,1],[2,1]]
node6 = Node(1)
node7 = Node(2)
node6.next = node7
node6.random = node6
node7.random = node6
copy2 = copyRandomList(node6)
print(print_list(copy2)) # [(1, 1), (2, 1)]
advanced

Instead of a hash map, interweave the clones into the original list temporarily. After the first pass, the structure is: original → clone → original → clone → .... In the second pass, the original node’s random neighbor is exactly one step away from the clone’s random neighbor. In the third pass, separate the two lists and restore the original.

This technique eliminates external storage for the mapping by reusing the list structure itself as a pointer table.

⏱ Time O(n) Three passes 💾 Space O(1) Only pointers, no extra map

Input: [[7,null],[13,0]]

Original: 7 → 13

StepStructureAction
17 → 7’ → 13 → 13’Interleave clones
27’ → null, 13’ → 7’Set random pointers
37 → 13 (restored), 7’ → 13’ → nullSeparate lists
function copyRandomListInterweave(head):
if head is null:
return null
// Pass 1: Interweave
current = head
while current != null:
copy = Node(current.val)
copy.next = current.next
current.next = copy
current = copy.next
// Pass 2: Set random pointers
current = head
while current != null:
if current.random != null:
current.next.random = current.random.next
current = current.next.next
// Pass 3: Separate lists
current = head
copyHead = head.next
while current != null:
copy = current.next
current.next = copy.next
copy.next = copy.next.next if copy.next else null
current = current.next
return copyHead
copy_list_with_random_pointer_interweave.py
from typing import Optional
class Node:
def __init__(self, x: int, next: "Node" = None, random: "Node" = None):
self.val = x
self.next = next
self.random = random
def copyRandomList(head: Optional[Node]) -> Optional[Node]:
if not head:
return None
# First pass: create copies and interleave them
# original -> copy -> original -> copy -> ...
current = head
while current:
copy = Node(current.val)
copy.next = current.next
current.next = copy
current = copy.next
# Second pass: set random pointers for copy nodes
current = head
while current:
if current.random:
current.next.random = current.random.next
current = current.next.next
# Third pass: restore original list and extract copy list
current = head
copy_head = head.next
while current:
copy = current.next
current.next = copy.next
copy.next = copy.next.next if copy.next else None
current = current.next
return copy_head
# Test cases
def print_list(head: Optional[Node]):
result = []
current = head
while current:
result.append((current.val, current.random.val if current.random else None))
current = current.next
return result
# Example 1: [[7,None],[13,0],[11,4],[10,2],[1,0]]
node1 = Node(7)
node2 = Node(13)
node3 = Node(11)
node4 = Node(10)
node5 = Node(1)
node1.next = node2
node2.next = node3
node3.next = node4
node4.next = node5
node1.random = None
node2.random = node1
node3.random = node5
node4.random = node3
node5.random = node1
copy = copyRandomList(node1)
print(print_list(copy)) # [(7, None), (13, 7), (11, 1), (10, 11), (1, 7)]
# Example 2: [[1,1],[2,1]]
node6 = Node(1)
node7 = Node(2)
node6.next = node7
node6.random = node6
node7.random = node6
copy2 = copyRandomList(node6)
print(print_list(copy2)) # [(1, 1), (2, 1)]
✓ Simple

A third approach demonstrating an alternative technique for solving this problem. This implementation optimizes either time or space complexity compared to the previous approaches.

⏱ Time O(n) Optimized complexity 💾 Space O(1) Efficient space usage
function approach3():
// Implementation approach goes here
copy_list_with_random_pointer_space_optimized.py
"""
Solution for Copy List with Random Pointer
"""
def solve():
"""Implementation for approach 3 of Copy List with Random Pointer"""
pass
if __name__ == "__main__":
print("Solution ready")