Find Middle Element of Linked List in DSA C# - Time & Space Complexity
We want to understand 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 class Node {
public int Value;
public Node Next;
}
public Node FindMiddle(Node head) {
Node slow = head, fast = head;
while (fast != null && fast.Next != null) {
slow = slow.Next;
fast = fast.Next.Next;
}
return slow;
}
This code finds the middle node of a linked list by moving two pointers at different speeds.
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 number of nodes in the list (n/2 times).
As the list size grows, the number of 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 grow linearly with the size of the list, just half as many steps as nodes.
Time Complexity: O(n)
This means the time to find the middle grows directly in proportion to the list size.
[X] Wrong: "The loop runs n times, so it takes twice as long as needed."
[OK] Correct: The fast pointer moves two steps each time, so the loop only runs about n/2 times, which is still linear time.
Understanding this pattern helps you quickly analyze linked list problems and shows you can reason about pointer movement efficiently.
"What if we used only one pointer moving one step at a time? How would the time complexity change?"
Practice
Solution
Step 1: Understand two-pointer movement
The slow pointer moves one node at a time, while the fast pointer moves two nodes at a time.Step 2: Identify middle when fast pointer ends
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 DQuick Check:
Two-pointer technique = slow one step, fast two steps [OK]
- Moving both pointers at the same speed
- Not checking for null before moving fast pointer
- Counting nodes first instead of using pointers
head?Solution
Step 1: Check pointer initialization
Both slow and fast pointers should start at the head of the list to traverse correctly.Step 2: Validate options
Only ListNode slow = head; ListNode fast = head; initializes both pointers at head, allowing proper traversal.Final Answer:
ListNode slow = head; ListNode fast = head; -> Option AQuick Check:
Both pointers start at head [OK]
- Starting slow or fast pointer at null
- Starting fast pointer too far ahead causing null errors
- Using head.next without checking for null
class ListNode {
public int val;
public ListNode next;
public ListNode(int x) { val = x; next = null; }
}
ListNode head = new ListNode(10);
head.next = new ListNode(20);
head.next.next = new ListNode(30);
head.next.next.next = new ListNode(40);
head.next.next.next.next = new ListNode(50);
ListNode slow = head, fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
Console.WriteLine(slow.val);Solution
Step 1: Trace pointer movement
Initial: slow=10, fast=10
Iteration 1: slow=20, fast=30
Iteration 2: slow=30, fast=50
Iteration 3: fast.next is null, loop ends.Step 2: Identify middle element
Slow pointer is at node with value 30, which is the middle of the list.Final Answer:
30 -> Option AQuick Check:
Middle element = 30 [OK]
- Assuming middle is 20 or 40 without tracing
- Not checking fast.next before moving fast
- Confusing slow and fast pointer positions
NullReferenceException. What is the error?ListNode slow = head;
ListNode fast = head;
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
Console.WriteLine(slow.val);Solution
Step 1: Analyze while loop condition
The condition checks fast.next and fast.next.next but does not check if fast itself is null, which can cause NullReferenceException.Step 2: Correct condition order
Check if fast != null before accessing fast.next to avoid exceptions.Final Answer:
The while condition should check if fast is null before fast.next -> Option CQuick Check:
Check fast != null before fast.next to avoid errors [OK]
- Checking fast.next before fast itself
- Moving slow pointer incorrectly
- Starting fast pointer at wrong node
Solution
Step 1: Understand default behavior
Normally, the two-pointer method returns the second middle node for even-length lists.Step 2: Modify pointer start positions
Starting the fast pointer at head.next and slow at head with the usual loop condition causes the slow pointer to stop at the first middle node.Final Answer:
Start fast pointer at head.next and slow at head, with the usual loop condition -> Option BQuick Check:
Adjust pointer start positions to get first middle [OK]
- Swapping slow and fast pointer speeds incorrectly
- Starting fast pointer at wrong node
- Using extra data structures unnecessarily
Ready to prove it?
Pass the test and this pattern moves unknown
