🧠
Brute Force (Using Hash Map for Node Mapping)
💡 This approach uses extra space to map original nodes to their copies. It is straightforward and helps beginners understand the problem by separating node creation and pointer assignment.
Intuition
Create a new node for each original node and store the mapping. Then assign next and random pointers for the copied nodes using this map.
Algorithm
- Traverse the original list and create a copy of each node, storing the mapping from original to copy in a hash map.
- Traverse the original list again to assign next and random pointers for each copied node using the hash map.
- Return the copied node corresponding to the original head.
💡 Separating node creation and pointer assignment makes it easier to understand and debug.
class Node:
def __init__(self, val, next=None, random=None):
self.val = val
self.next = next
self.random = random
def copyRandomList(head):
if not head:
return None
old_to_new = {}
curr = head
while curr:
old_to_new[curr] = Node(curr.val)
curr = curr.next
curr = head
while curr:
old_to_new[curr].next = old_to_new.get(curr.next)
old_to_new[curr].random = old_to_new.get(curr.random)
curr = curr.next
return old_to_new[head]
# Driver code to test
if __name__ == '__main__':
# Create list: 7->13->11->10->1 with random pointers
nodes = [Node(7), Node(13), Node(11), Node(10), Node(1)]
nodes[0].next = nodes[1]
nodes[1].next = nodes[2]
nodes[2].next = nodes[3]
nodes[3].next = nodes[4]
nodes[1].random = nodes[0]
nodes[2].random = nodes[4]
nodes[3].random = nodes[2]
nodes[4].random = nodes[0]
copied_head = copyRandomList(nodes[0])
print(copied_head.val) # Should print 7
Line Notes
class Node:Defines the node structure with val, next, and random pointers
old_to_new = {}Creates a dictionary to map original nodes to their copies
while curr:First pass to create all new nodes without setting pointers
old_to_new[curr] = Node(curr.val)Creates a new node for each original node
old_to_new[curr].next = old_to_new.get(curr.next)Assigns the next pointer for the copied node using the map
old_to_new[curr].random = old_to_new.get(curr.random)Assigns the random pointer for the copied node using the map
return old_to_new[head]Returns the head of the copied list
import java.util.HashMap;
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
public class Solution {
public Node copyRandomList(Node head) {
if (head == null) return null;
HashMap<Node, Node> map = new HashMap<>();
Node curr = head;
while (curr != null) {
map.put(curr, new Node(curr.val));
curr = curr.next;
}
curr = head;
while (curr != null) {
map.get(curr).next = map.get(curr.next);
map.get(curr).random = map.get(curr.random);
curr = curr.next;
}
return map.get(head);
}
// Driver code
public static void main(String[] args) {
Node[] nodes = new Node[5];
nodes[0] = new Node(7);
nodes[1] = new Node(13);
nodes[2] = new Node(11);
nodes[3] = new Node(10);
nodes[4] = new Node(1);
nodes[0].next = nodes[1];
nodes[1].next = nodes[2];
nodes[2].next = nodes[3];
nodes[3].next = nodes[4];
nodes[1].random = nodes[0];
nodes[2].random = nodes[4];
nodes[3].random = nodes[2];
nodes[4].random = nodes[0];
Solution sol = new Solution();
Node copiedHead = sol.copyRandomList(nodes[0]);
System.out.println(copiedHead.val); // Should print 7
}
}
Line Notes
import java.util.HashMap;Imports HashMap for mapping original to copied nodes
HashMap<Node, Node> map = new HashMap<>();Stores mapping from original to copied nodes
while (curr != null)First pass to create new nodes
map.put(curr, new Node(curr.val));Creates a copy of the current node
map.get(curr).next = map.get(curr.next);Assigns next pointer for copied node
map.get(curr).random = map.get(curr.random);Assigns random pointer for copied node
return map.get(head);Returns the copied list's head
#include <iostream>
#include <unordered_map>
using namespace std;
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = nullptr;
random = nullptr;
}
};
class Solution {
public:
Node* copyRandomList(Node* head) {
if (!head) return nullptr;
unordered_map<Node*, Node*> map;
Node* curr = head;
while (curr) {
map[curr] = new Node(curr->val);
curr = curr->next;
}
curr = head;
while (curr) {
map[curr]->next = map[curr->next];
map[curr]->random = map[curr->random];
curr = curr->next;
}
return map[head];
}
};
// Driver code
int main() {
Node* nodes[5] = {new Node(7), new Node(13), new Node(11), new Node(10), new Node(1)};
nodes[0]->next = nodes[1];
nodes[1]->next = nodes[2];
nodes[2]->next = nodes[3];
nodes[3]->next = nodes[4];
nodes[1]->random = nodes[0];
nodes[2]->random = nodes[4];
nodes[3]->random = nodes[2];
nodes[4]->random = nodes[0];
Solution sol;
Node* copiedHead = sol.copyRandomList(nodes[0]);
cout << copiedHead->val << endl; // Should print 7
return 0;
}
Line Notes
#include <unordered_map>Includes unordered_map for mapping original to copied nodes
unordered_map<Node*, Node*> map;Maps original nodes to their copies
while (curr) {First pass to create new nodes
map[curr] = new Node(curr->val);Creates a new node copy
map[curr]->next = map[curr->next];Assigns next pointer for copied node
map[curr]->random = map[curr->random];Assigns random pointer for copied node
return map[head];Returns the head of the copied list
function Node(val, next = null, random = null) {
this.val = val;
this.next = next;
this.random = random;
}
var copyRandomList = function(head) {
if (!head) return null;
const map = new Map();
let curr = head;
while (curr) {
map.set(curr, new Node(curr.val));
curr = curr.next;
}
curr = head;
while (curr) {
map.get(curr).next = map.get(curr.next) || null;
map.get(curr).random = map.get(curr.random) || null;
curr = curr.next;
}
return map.get(head);
};
// Driver code
const nodes = [new Node(7), new Node(13), new Node(11), new Node(10), new Node(1)];
nodes[0].next = nodes[1];
nodes[1].next = nodes[2];
nodes[2].next = nodes[3];
nodes[3].next = nodes[4];
nodes[1].random = nodes[0];
nodes[2].random = nodes[4];
nodes[3].random = nodes[2];
nodes[4].random = nodes[0];
const copiedHead = copyRandomList(nodes[0]);
console.log(copiedHead.val); // Should print 7
Line Notes
function Node(val, next = null, random = null) {Defines the node structure with val, next, and random pointers
const map = new Map();Stores mapping from original nodes to copied nodes
while (curr) {First pass to create copies of nodes
map.set(curr, new Node(curr.val));Creates a new node copy
map.get(curr).next = map.get(curr.next) || null;Assigns next pointer for copied node
map.get(curr).random = map.get(curr.random) || null;Assigns random pointer for copied node
return map.get(head);Returns the copied list's head
We traverse the list twice, each O(n). The hash map stores n nodes, so O(n) space.
💡 For n=100,000 nodes, this means about 200,000 operations plus memory for 100,000 node mappings.
Interview Verdict: Accepted
This approach is accepted but uses extra space. It is a good starting point to understand the problem.