Insert at End Tail Insert in DSA Typescript - Time & Space Complexity
We want to understand how long it takes to add a new item at the end of a list.
How does the time needed change as the list grows bigger?
Analyze the time complexity of the following code snippet.
class Node {
value: number;
next: Node | null = null;
constructor(value: number) {
this.value = value;
}
}
function insertAtEnd(head: Node | null, value: number): Node {
const newNode = new Node(value);
if (!head) return newNode;
let current = head;
while (current.next !== null) {
current = current.next;
}
current.next = newNode;
return head;
}
This code adds a new node with a given value at the end of a singly linked list.
- Primary operation: The while loop that moves through each node until the last one.
- How many times: It runs once for each node in the list until it reaches the end.
As the list gets longer, the time to find the end grows too.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 steps to reach the end |
| 100 | About 100 steps to reach the end |
| 1000 | About 1000 steps to reach the end |
Pattern observation: The steps grow directly with the number of nodes; doubling nodes doubles the steps.
Time Complexity: O(n)
This means the time to insert at the end grows linearly with the list size.
[X] Wrong: "Inserting at the end is always instant, no matter the list size."
[OK] Correct: Because we must walk through all nodes to find the end, the time grows with the list length.
Knowing how insertion time grows helps you explain trade-offs in list designs and shows you understand linked list basics.
"What if we kept a pointer to the last node? How would the time complexity change?"
Practice
Solution
Step 1: Understand the operation
Insert at End means adding a new node after the last node in the list.Step 2: Compare with other operations
Adding at the beginning or deleting nodes are different operations.Final Answer:
Adds a new node at the end of the list -> Option BQuick Check:
Insert at End = Add node at tail [OK]
- Confusing tail insert with head insert
- Thinking it deletes nodes
- Assuming it inserts in the middle
Solution
Step 1: Recall TypeScript class instantiation
To create an instance of a class, use the 'new' keyword with constructor.Step 2: Check each option
const newNode = new Node(value); uses 'new Node(value);' which is correct syntax.Final Answer:
const newNode = new Node(value); -> Option AQuick Check:
Use 'new' keyword to create class instance [OK]
- Omitting 'new' keyword
- Calling class like a function
- Using undefined methods like create()
class Node {
value: number;
next: Node | null = null;
constructor(value: number) { this.value = value; }
}
class LinkedList {
head: Node | null = null;
insertAtEnd(value: number) {
const newNode = new Node(value);
if (!this.head) {
this.head = newNode;
return;
}
let current = this.head;
while (current.next) {
current = current.next;
}
current.next = newNode;
}
}
const list = new LinkedList();
list.insertAtEnd(5);
list.insertAtEnd(10);
list.insertAtEnd(15);
// What is the linked list after these insertions?Solution
Step 1: Insert 5 into empty list
Since head is null, head becomes node with value 5.Step 2: Insert 10 at end
Traverse from head (5), next is null, so set next to new node 10.Step 3: Insert 15 at end
Traverse from head (5) to 10, next is null, set next to new node 15.Final Answer:
5 -> 10 -> 15 -> null -> Option DQuick Check:
Nodes added in order at tail [OK]
- Assuming insertion at head
- Mixing node order
- Not updating next pointers correctly
insertAtEnd(value: number) {
const newNode = new Node(value);
if (!this.head) {
this.head = newNode;
}
let current = this.head;
while (current.next) {
current = current.next;
}
current.next = newNode;
}
What is the error in this code?Solution
Step 1: Analyze empty list case
If head is null, head is set to newNode, but code continues to traverse and insert again.Step 2: Identify double insertion
After setting head, it still traverses and sets current.next = newNode, adding newNode twice.Final Answer:
It inserts the new node twice when the list is empty -> Option AQuick Check:
Missing return after head assignment causes double insert [OK]
- Not returning after head assignment
- Assuming single insertion always
- Ignoring traversal logic
Solution
Step 1: Understand traversal cost
Without a tail pointer, inserting at end requires traversing all nodes, which is slow for long lists.Step 2: Use tail pointer
Maintaining a tail pointer lets you directly access the last node and insert in constant time.Step 3: Evaluate other options
Inserting at head changes order, doubly linked list adds complexity, length doesn't help find last node efficiently.Final Answer:
Keep a tail pointer that always points to the last node -> Option CQuick Check:
Tail pointer = O(1) insert at end [OK]
- Thinking length helps find last node
- Confusing head insertion with tail insertion
- Ignoring complexity of doubly linked list
Ready to prove it?
Pass the test and this pattern moves unknown
