Clone Linked List with Random Pointer in DSA C# - Time & Space Complexity
We want to understand how the time needed to clone a linked list with random pointers changes as the list grows.
How does the number of steps grow when the list gets longer?
Analyze the time complexity of the following code snippet.
public Node CloneList(Node head) {
if (head == null) return null;
Node curr = head;
while (curr != null) {
Node copy = new Node(curr.val);
copy.next = curr.next;
curr.next = copy;
curr = copy.next;
}
curr = head;
while (curr != null) {
if (curr.random != null) curr.next.random = curr.random.next;
curr = curr.next.next;
}
curr = head;
Node copyHead = head.next;
while (curr != null) {
Node copy = curr.next;
curr.next = copy.next;
if (copy.next != null) copy.next = copy.next.next;
curr = curr.next;
}
return copyHead;
}
This code creates a deep copy of a linked list where each node has a next and a random pointer.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Three separate while loops that each go through the entire list once.
- How many times: Each loop runs once over all nodes, so about n times each, where n is the number of nodes.
Each loop runs through the list once, so the total steps grow roughly three times the number of nodes.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 30 steps |
| 100 | About 300 steps |
| 1000 | About 3000 steps |
Pattern observation: The total work grows linearly as the list gets longer.
Time Complexity: O(n)
This means the time to clone the list grows in direct proportion to the number of nodes.
[X] Wrong: "Because there are three loops, the time complexity is O(n³)."
[OK] Correct: The loops run one after another, not nested inside each other, so their times add up, not multiply.
Understanding this helps you explain how to efficiently copy complex linked structures, a skill useful in many coding challenges.
"What if the random pointer could point to any node in a separate list? How would the time complexity change?"
Practice
Solution
Step 1: Understand the structure of the linked list
The linked list has two pointers: next and random. The next pointer points to the next node, and the random pointer can point to any node or null.Step 2: Identify the cloning challenge
While cloning, copying next pointers is straightforward, but random pointers can point anywhere, so they must be copied carefully to preserve the original structure.Final Answer:
Copying the next pointers correctly while preserving the random pointers -> Option CQuick Check:
Random pointer preservation = main cloning challenge [OK]
- Ignoring random pointers during cloning
- Assuming random pointers follow next pointers
- Trying to sort or reverse the list before cloning
Solution
Step 1: Check for correct access modifiers and constructor
public class Node { public int val; public Node next; public Node random; public Node(int val) { this.val = val; next = null; random = null; } } declares a public class with public fields and a constructor initializing val, next, and random to null, which is correct.Step 2: Identify issues in other options
public class Node { int val; Node next; Node random; } lacks access modifiers and constructor. class Node { public int val; public Node next; } misses random pointer. public struct Node { public int val; public Node next; public Node random; } uses struct which is not ideal for linked list nodes.Final Answer:
Option A code snippet correctly declares the node class -> Option AQuick Check:
Public class with constructor = correct node declaration [OK]
- Missing public access modifiers
- Not initializing pointers in constructor
- Using struct instead of class for nodes
Node head = new Node(1);
head.next = new Node(2);
head.next.next = new Node(3);
head.random = head.next.next; // 1's random points to 3
head.next.random = head; // 2's random points to 1
head.next.next.random = head.next; // 3's random points to 2
Node clonedHead = CloneLinkedList(head);
Node current = clonedHead;
while (current != null) {
Console.Write(current.val + " ");
current = current.next;
}Solution
Step 1: Understand the original list structure
The original list nodes are 1 -> 2 -> 3 with next pointers in that order. Random pointers do not affect the order of next pointers.Step 2: Cloning preserves next order
The CloneLinkedList function clones nodes preserving the next pointer order, so the cloned list will have nodes 1 -> 2 -> 3 in sequence.Final Answer:
1 2 3 -> Option BQuick Check:
Next pointers order = 1 2 3 [OK]
- Confusing random pointer order with next pointer order
- Assuming cloned list reverses nodes
- Printing random pointer values instead of node values
public Node CloneLinkedList(Node head) {
if (head == null) return null;
Node current = head;
while (current != null) {
Node copy = new Node(current.val);
copy.next = current.next;
current.next = copy;
current = current.next;
}
// Setting random pointers omitted for brevity
return head.next;
}Solution
Step 1: Analyze the while loop pointer update
Inside the loop, current is updated with current = current.next, but after insertion, current.next points to the copy node, so current moves to copy node again, causing an infinite loop.Step 2: Correct pointer update to skip copy node
To avoid infinite loop, current should be updated to current.next.next to move to the next original node.Final Answer:
The current pointer update causes an infinite loop -> Option DQuick Check:
Pointer update must skip copy node to avoid infinite loop [OK]
- Updating current to current.next causes infinite loop
- Forgetting to set random pointers
- Returning original head instead of cloned head
Solution
Step 1: Understand space and time constraints
O(n) time and O(1) extra space means no extra data structures like hash maps can be used.Step 2: Use interleaving method
Interleave cloned nodes between original nodes, set random pointers using original nodes, then separate the two lists. This uses no extra space and runs in linear time.Final Answer:
Interleave cloned nodes with original nodes, set random pointers, then separate lists -> Option AQuick Check:
Interleaving nodes = O(n) time & O(1) space cloning [OK]
- Using hash map increases space to O(n)
- Ignoring random pointers during cloning
- Reversing list does not help cloning random pointers
Ready to prove it?
Pass the test and this pattern moves unknown
