Insert at Beginning of Circular Linked List in DSA Typescript - Time & Space Complexity
We want to understand how long it takes to add a new node at the start of a circular linked list.
How does the time needed change as the list grows?
Analyze the time complexity of the following code snippet.
function insertAtBeginning(head: Node | null, data: number): Node {
const newNode = new Node(data);
if (!head) {
newNode.next = newNode;
return newNode;
}
let temp = head;
while (temp.next !== head) {
temp = temp.next;
}
temp.next = newNode;
newNode.next = head;
return newNode;
}
This code adds a new node at the start of a circular linked list by first finding the last node.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that moves through the list to find the last node.
- How many times: It runs once for each node until it reaches the last node, so roughly n times for a list of size n.
As the list gets bigger, the loop runs more times to find the last node.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 steps to find last node |
| 100 | About 100 steps to find last node |
| 1000 | About 1000 steps to find last node |
Pattern observation: The time grows roughly in direct proportion to the list size.
Time Complexity: O(n)
This means adding at the beginning takes longer as the list grows because we must find the last node first.
[X] Wrong: "Inserting at the beginning is always fast and takes constant time."
[OK] Correct: Because we need to find the last node to update its pointer, the time depends on the list size, not constant.
Understanding this helps you explain how linked list operations depend on structure and pointers, a key skill in many coding challenges.
What if we kept a pointer to the last node? How would the time complexity change?
Practice
Solution
Step 1: Understand the circular linked list structure
A circular linked list has its last node pointing back to the head node, forming a circle.Step 2: Insert new node at beginning
The new node is linked to the current head, and the last node's next pointer is updated to this new node, making it the new head.Final Answer:
The new node becomes the head and points to the old head, maintaining the circular link. -> Option DQuick Check:
New head points to old head, circle intact [OK]
- Forgetting to update last node's next pointer
- Breaking the circular link by not connecting last node
- Replacing the last node instead of adding new head
Solution
Step 1: Link new node to current head
newNode.next = head sets the new node's next pointer to the current head.Step 2: Update last node's next pointer and head
last.next = newNode updates the last node to point to the new node, and head = newNode sets the new node as the head.Final Answer:
newNode.next = head; last.next = newNode; head = newNode; -> Option AQuick Check:
Correct pointer updates maintain circular list [OK]
- Setting newNode.next to null breaks circularity
- Not updating last.next to newNode
- Assigning head incorrectly before linking nodes
class Node {
data: number;
next: Node | null;
constructor(data: number) {
this.data = data;
this.next = null;
}
}
let head = new Node(10);
let second = new Node(20);
let third = new Node(30);
head.next = second;
second.next = third;
third.next = head; // circular link
let newNode = new Node(5);
// Insert at beginning
newNode.next = head;
third.next = newNode;
head = newNode;
// Print list
let temp = head;
do {
console.log(temp.data);
temp = temp.next!;
} while (temp !== head);Solution
Step 1: Understand the initial circular list
Initial list is 10 -> 20 -> 30 -> back to 10 (circular).Step 2: Insert new node with data 5 at beginning
newNode.next = head points 5 to 10; third.next = newNode points 30 to 5; head = newNode updates head to 5.Step 3: Print traversal
Starting at head (5), traversal prints 5, 10, 20, 30, then stops as it loops back to 5.Final Answer:
5 -> 10 -> 20 -> 30 (circular) -> Option AQuick Check:
New head 5 leads list, circle intact [OK]
- Printing null at end instead of circular loop
- Not updating last node's next pointer
- Confusing order of nodes after insertion
newNode.next = head; head = newNode; last.next = newNode;
Solution
Step 1: Analyze pointer updates order
newNode.next = head sets new node's next to old head correctly.Step 2: Verify the updates
head = newNode updates head to new node. Then last.next = newNode correctly sets the last node's next to the new head since 'last' references the unchanged last node.Step 3: Confirm circularity
The final structure is newHead -> oldHead -> ... -> last -> newHead, fully circular with no breaks.Final Answer:
No error; code correctly inserts at beginning. -> Option BQuick Check:
last reference stable, circle intact [OK]
- Assuming changing head before last.next breaks circle
- Not updating last.next at all
- Pointing newNode.next incorrectly
Solution
Step 1: Link new node to current head
newNode.next = head points the new node (5) to the current head (15).Step 2: Update last node's next pointer
last.next = newNode updates the last node (35) to point to the new node (5), maintaining circularity.Step 3: Update head pointer
head = newNode sets the new node as the head of the list.Final Answer:
Set newNode.next = head; last.next = newNode; head = newNode; -> Option CQuick Check:
New head points to old head; last points to new head [OK]
- Updating pointers in wrong order
- Pointing newNode.next to last instead of head
- Not updating last.next to newNode
Ready to prove it?
Pass the test and this pattern moves unknown
