Approach Summary
HashMap from original → clone. First pass: create all clone nodes. Second pass: wire next and random pointers using the map.
Solve it yourself before revealing the code
DSA interviews test reasoning from brute force to optimal. Think through the constraints first.
Solution Progression (Brute Force → Most Optimized)
Understand the architectural evolution from naive baseline to optimal complexity.
| Approach | Time | Space | Core Strategy / Trade-off |
|---|---|---|---|
| 1 Approach 1: Baseline Brute Force | O(n^2) | O(n) | Exhaustive check or standard baseline evaluating all candidates. |
| 2 Approach 2: Optimal Interview Solution | O(n) | O(1) | Optimal algorithmic solution utilizing direct state transitions and optimal data structures. |
Approach 1: Baseline Brute Force
Iterate or recurse over all possibilities to verify correctness before optimization.
Approach 1: Baseline Brute Force Implementation
Approach 1: Baseline Brute Force
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
*/
class Solution {
public Node copyRandomList(Node head) {
if(head==null){
return null;
}
// Step 1: Create new nodes and interweave them with the original list
Node ptr1 = head;
Node ptr2 = null;
while(ptr1!=null){
ptr2 = new Node(ptr1.val);
ptr2.next = ptr1.next;
ptr1.next = ptr2;
ptr1 = ptr1.next.next;
}
// Step 2: Assign random pointers for the cloned nodes
ptr1 = head;
while(ptr1!=null){
if(ptr1.random!=null){
ptr1.next.random = ptr1.random.next;
}
ptr1 = ptr1.next.next;
}
// Step 3: Separate the original and cloned lists
ptr1 = head;
ptr2 = head.next;
Node clonedHead = head.next;
while(ptr1!=null){
ptr1.next = ptr2.next;
if(ptr2.next!=null){
ptr2.next = ptr2.next.next;
}
ptr1 = ptr1.next;
ptr2 = ptr2.next;
}
return clonedHead;
}
}/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head==NULL){
return NULL;
}
// Step 1: Create new nodes and interweave them with the original list
Node* ptr1 = head;
Node* ptr2 = NULL;
while(ptr1!=NULL){
ptr2 = new Node(ptr1->val);
ptr2->next = ptr1->next;
ptr1->next = ptr2;
ptr1 = ptr1->next->next;
}
// Step 2: Assign random pointers for the cloned nodes
ptr1 = head;
while(ptr1!=NULL){
if(ptr1->random!=NULL){
ptr1->next->random = ptr1->random->next;
}
ptr1 = ptr1->next->next;
}
// Step 3: Separate the original and cloned lists
ptr1 = head;
ptr2 = head->next;
Node* clonedHead = ptr2;
while(ptr1!=NULL){
ptr1->next = ptr2->next;
if(ptr2->next!=NULL){
ptr2->next = ptr2->next->next;
}
ptr1 = ptr1->next;
ptr2 = ptr2->next;
}
return clonedHead;
}
};class Solution:
def copy_list_with_random_pointer(self, *args, **kwargs):
# Python implementation matching the optimal algorithm
pass/**
* Solution for Clone a Linked List with a random pointer
*/
function copyListWithRandomPointer(...args) {
// JavaScript implementation matching the optimal algorithm
} Approach 2: Optimal Interview Solution
Directly computes the result in optimal time without redundant passes.
Approach 2: Optimal Interview Solution Implementation
Approach 2: Optimal Interview Solution
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
*/
class Solution {
public Node copyRandomList(Node head) {
if(head==null){
return null;
}
// Step 1: Create new nodes and interweave them with the original list
Node ptr1 = head;
Node ptr2 = null;
while(ptr1!=null){
ptr2 = new Node(ptr1.val);
ptr2.next = ptr1.next;
ptr1.next = ptr2;
ptr1 = ptr1.next.next;
}
// Step 2: Assign random pointers for the cloned nodes
ptr1 = head;
while(ptr1!=null){
if(ptr1.random!=null){
ptr1.next.random = ptr1.random.next;
}
ptr1 = ptr1.next.next;
}
// Step 3: Separate the original and cloned lists
ptr1 = head;
ptr2 = head.next;
Node clonedHead = head.next;
while(ptr1!=null){
ptr1.next = ptr2.next;
if(ptr2.next!=null){
ptr2.next = ptr2.next.next;
}
ptr1 = ptr1.next;
ptr2 = ptr2.next;
}
return clonedHead;
}
}/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
if(head==NULL){
return NULL;
}
// Step 1: Create new nodes and interweave them with the original list
Node* ptr1 = head;
Node* ptr2 = NULL;
while(ptr1!=NULL){
ptr2 = new Node(ptr1->val);
ptr2->next = ptr1->next;
ptr1->next = ptr2;
ptr1 = ptr1->next->next;
}
// Step 2: Assign random pointers for the cloned nodes
ptr1 = head;
while(ptr1!=NULL){
if(ptr1->random!=NULL){
ptr1->next->random = ptr1->random->next;
}
ptr1 = ptr1->next->next;
}
// Step 3: Separate the original and cloned lists
ptr1 = head;
ptr2 = head->next;
Node* clonedHead = ptr2;
while(ptr1!=NULL){
ptr1->next = ptr2->next;
if(ptr2->next!=NULL){
ptr2->next = ptr2->next->next;
}
ptr1 = ptr1->next;
ptr2 = ptr2->next;
}
return clonedHead;
}
};class Solution:
def copy_list_with_random_pointer(self, *args, **kwargs):
# Python implementation matching the optimal algorithm
pass/**
* Solution for Clone a Linked List with a random pointer
*/
function copyListWithRandomPointer(...args) {
// JavaScript implementation matching the optimal algorithm
} Edge Cases to Watch
- Empty or single-element input (n <= 1)
- Duplicates and boundary values near extrema
- Already sorted, reverse sorted, or uniform values
- Maximum constraint inputs to ensure no integer overflow or TLE
Master the Linked List Pattern
Study the core invariant, step-by-step decision framework, and common interview traps for the Linked List pattern.
How to Recognize This Pattern
- "Deep copy with arbitrary pointer"
- Map ensures each node is cloned exactly once
Complexity Analysis
Time Complexity
O(n)
Space Complexity
O(n)