Find Middle Element of Linked List in DSA Javascript - Time & Space Complexity
We want to know how long it takes to find the middle element in a linked list as the list grows.
How does the time needed change when the list gets bigger?
Analyze the time complexity of the following code snippet.
function findMiddle(head) {
let slow = head;
let fast = head;
while (fast !== null && fast.next !== null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
This code uses two pointers moving at different speeds to find the middle node of a linked list.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that moves the fast and slow pointers through the list.
- How many times: The loop runs about half the length of the list, since fast moves two steps each time.
As the list size grows, the number of loop steps grows roughly half as fast.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 5 steps |
| 100 | About 50 steps |
| 1000 | About 500 steps |
Pattern observation: The steps increase linearly with input size, but only about half as many because of the fast pointer.
Time Complexity: O(n)
This means the time to find the middle grows in direct proportion to the list size.
[X] Wrong: "Since the fast pointer jumps two steps, the time complexity is O(n/2), which is faster than O(n)."
[OK] Correct: We ignore constants in Big-O, so O(n/2) is the same as O(n). The time still grows linearly with input size.
Understanding this pattern shows you can use clever pointer techniques to solve problems efficiently, a skill valued in many coding challenges.
"What if we used only one pointer moving one step at a time to find the middle? How would the time complexity change?"
Practice
Solution
Step 1: Understand two-pointer technique
One pointer (fast) moves two nodes at a time, the other (slow) moves one node at a time.Step 2: Identify middle when fast pointer reaches end
When fast pointer reaches the end of the list, slow pointer will be at the middle node.Final Answer:
Use one pointer moving twice as fast as the other; when fast reaches end, slow is at middle -> Option BQuick Check:
Two-pointer technique = fast & slow pointers [OK]
- Trying to reverse the list unnecessarily
- Counting nodes twice instead of using two pointers
- Moving both pointers at the same speed
head?Solution
Step 1: Initialize both pointers at head
Both slow and fast pointers start at the head node to begin traversal.Step 2: Confirm correct initialization
Starting both at head allows fast to move ahead and slow to lag behind properly.Final Answer:
let slow = head; let fast = head; -> Option CQuick Check:
Both pointers start at head [OK]
- Starting slow or fast at null or head.next incorrectly
- Swapping slow and fast initialization
- Starting fast pointer at null causing errors
class Node {
constructor(value) {
this.value = value;
this.next = null;
}
}
const head = new Node(10);
head.next = new Node(20);
head.next.next = new Node(30);
head.next.next.next = new Node(40);
head.next.next.next.next = new Node(50);
function findMiddle(head) {
let slow = head;
let fast = head;
while (fast !== null && fast.next !== null) {
slow = slow.next;
fast = fast.next.next;
}
return slow.value;
}
console.log(findMiddle(head));Solution
Step 1: Trace slow and fast pointers through the list
Initially, slow=10, fast=10. After first loop: slow=20, fast=30. Second loop: slow=30, fast=50. Third loop ends as fast.next is null.Step 2: Identify slow pointer value at loop end
Slow pointer is at node with value 30, which is the middle element.Final Answer:
30 -> Option DQuick Check:
Middle element = 30 [OK]
- Returning fast pointer value instead of slow
- Off-by-one error in loop condition
- Confusing node values during traversal
function findMiddle(head) {
let slow = head;
let fast = head.next;
while (fast !== null && fast.next !== null) {
slow = slow.next;
fast = fast.next.next;
}
return slow.value;
}Solution
Step 1: Analyze pointer initialization
Fast pointer starts at head.next, which causes slow pointer to point to the first middle in even-length lists incorrectly.Step 2: Correct initialization for accurate middle
Fast pointer should start at head to ensure slow pointer reaches the true middle node.Final Answer:
Fast pointer should start at head, not head.next -> Option AQuick Check:
Fast pointer must start at head [OK]
- Starting fast pointer at head.next causing wrong middle
- Changing loop condition incorrectly
- Returning fast pointer value instead of slow
Solution
Step 1: Understand default behavior
Normally, both pointers start at head, so slow points to second middle in even-length lists.Step 2: Modify initialization to get first middle
Starting fast pointer at head.next causes slow pointer to move fewer steps, landing on the first middle node.Final Answer:
Initialize fast pointer at head.next and slow pointer at head -> Option AQuick Check:
Fast starts at head.next for first middle [OK]
- Swapping slow and fast initialization incorrectly
- Changing pointer movement speeds
- Returning fast pointer value without logic
Ready to prove it?
Pass the test and this pattern moves unknown
