Deep-Copy a Linked List with Random Pointers
SnowflakeSoftware Engineer · Technical ScreenLast updated
Implement a deep copy of a linked list where each node has both a next pointer and an arbitrary random pointer, ensuring all reachable nodes and relationships are replicated without modifying the original list.
Problem Statement
You are given the head of a singly linked list where each node contains an integer val, a next pointer pointing to the next node in the chain, and a random pointer which could point to any node in the list or None.
Construct a deep copy of the list reachable from head by following next pointers. 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 pointers of the copied nodes should point to new nodes in the copied list such that the original relationships are preserved. If a random pointer in the original list points to None, the copied node's random pointer must also be None.
None of the pointers in the new list should point to nodes in the original list, and the original list must not be permanently altered.
Return the head of the copied linked list.
Node Definition
class Node:
def __init__(self, val: int, next: 'Node' = None, random: 'Node' = None):
self.val = val
self.next = next
self.random = random
Function Signature
def copy_random_list(head: Optional[Node]) -> Optional[Node]:
pass
Examples
Example 1:
Input: head = [[7, null], [13, 0], [11, 4], [10, 2], [1, 0]]
Output: [[7, null], [13, 0], [11, 4], [10, 2], [1, 0]]
Explanation:
- Node 0 (val = 7): next -> Node 1, random -> None
- Node 1 (val = 13): next -> Node 2, random -> Node 0
- Node 2 (val = 11): next -> Node 3, random -> Node 4
- Node 3 (val = 10): next -> Node 4, random -> Node 2
- Node 4 (val = 1): next -> None, random -> Node 0
All nodes in the output are newly allocated.
Example 2:
Input: head = [[1, 1], [2, 1]]
Output: [[1, 1], [2, 1]]
Explanation:
- Node 0 has val = 1, next -> Node 1, random -> Node 0 (self-loop).
- Node 1 has val = 2, next -> None, random -> Node 0.
Constraints
- The number of nodes in the list is in the range
[0, 10^4]. -10^4 <= Node.val <= 10^4Node.randomisNoneor points to some node in the list reachable fromheadvianext.
Edge Cases
- Empty list (
head = None). - Single node with
random = Noneor self-referentialrandom. - All
randompointers pointing to the same node.
Hints
Hint 1
A direct pass using a hash map from original node references to newly created nodes allows looking up random targets in O(1) time.
Hint 2
To achieve O(1) auxiliary space, try weaving the copied nodes directly after their original counterparts (e.g., A -> A' -> B -> B').
Hint 3
If you weave the lists, set the random pointers for copied nodes using the original nodes' random targets, then carefully decouple the two lists to restore the original.
Follow-up questions
- How can you implement this with O(1) auxiliary space without using extra memory for a hash map?
- How would you adapt your algorithm if the list contains cycles in the next pointer chain?
- If the list is stored across distributed partitions and cannot fit into a single machine's memory, how would you approach the deep copy?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.