Find Middle Element of Linked List in DSA Java - 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.
public ListNode findMiddle(ListNode head) {
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
This code finds the middle node by moving one pointer twice as fast as the other.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The while loop that moves the slow and fast pointers through the list.
- How many times: The loop runs about half the length of the list because 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 | 5 |
| 100 | 50 |
| 1000 | 500 |
Pattern observation: The operations grow linearly with the size of the list.
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 still O(n). The time still grows linearly with input size.
Understanding this pattern helps you solve many linked list problems efficiently, a common skill interviewers look for.
"What if we used only one pointer to traverse the list once? How would the time complexity change?"
Practice
Solution
Step 1: Understand the two-pointer technique
The slow pointer moves one node at a time, while the fast pointer moves two nodes at a time.Step 2: Identify when to stop
When the fast pointer reaches the end (null), the slow pointer will be at the middle node.Final Answer:
Use one slow pointer moving one step and one fast pointer moving two steps until fast reaches the end -> Option CQuick Check:
Two-pointer technique = slow one step, fast two steps [OK]
- Moving both pointers at the same speed
- Counting nodes first then traversing again
- Stopping when slow pointer reaches null
head?Solution
Step 1: Initialize both pointers at the start
Both slow and fast pointers should start at the head node to cover the entire list.Step 2: Check initialization correctness
Node slow = head; Node fast = head; initializes both pointers to head, which is correct for the two-pointer approach.Final Answer:
Node slow = head; Node fast = head; -> Option AQuick Check:
Both pointers start at head [OK]
- Starting slow pointer at null
- Starting fast pointer ahead causing null errors
- Skipping nodes at initialization
class Node {
int data;
Node next;
Node(int d) { data = d; next = null; }
}
public class Test {
public static void main(String[] args) {
Node 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);
Node slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
System.out.println(slow.data);
}
}Solution
Step 1: Trace slow and fast pointers
Initially, slow=10, fast=10. After first loop: slow=20, fast=30. Second loop: slow=30, fast=50. Third loop: fast.next is null, loop ends.Step 2: Identify slow pointer position at loop end
Slow pointer is at node with data 30, which is the middle element.Final Answer:
30 -> Option DQuick Check:
Middle element = 30 [OK]
- Printing fast pointer data instead of slow
- Off-by-one errors in loop condition
- Assuming middle is first or last node
Node slow = head;
Node fast = head.next;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
System.out.println(slow.data);Solution
Step 1: Analyze pointer initialization
Fast pointer starts at head.next, which causes the slow pointer to point to the first middle in even-length lists.Step 2: Correct initialization for consistent middle
Initialize fast pointer at head to find the second middle element in even-length lists.Final Answer:
Initialize fast pointer to head instead of head.next -> Option BQuick Check:
Fast pointer starts at head for correct middle [OK]
- Starting fast pointer at head.next causing off-by-one
- Incorrect loop condition causing null pointer
- Moving slow pointer incorrectly
Solution
Step 1: Understand default behavior
Starting both pointers at head returns the second middle in even-length lists.Step 2: Modify initialization to get first middle
Starting fast pointer at head.next causes slow pointer to land on the first middle.Final Answer:
Initialize fast pointer to head.next and use the same loop condition -> Option AQuick Check:
Fast starts at head.next for first middle [OK]
- Changing loop condition incorrectly
- Moving pointers in wrong directions
- Starting slow pointer ahead causing errors
Ready to prove it?
Pass the test and this pattern moves unknown
