Skip to content
← All posts

Middle of the Linked List: The Slow and Fast Pointer Technique

4 min read
leetcodeproblemeasylinked-liststwo-pointers

Middle of the Linked List is LeetCode problem 876. Given the head of a singly linked list, return the middle node. If there are two middle nodes (even-length list), return the second one.

You could solve this in two passes by counting the total length first and then walking to n / 2. But there is a one-pass solution that uses the slow and fast pointer technique. It is cleaner, and it introduces a pattern you will use again and again in linked list problems.

12345headslowfastmiddle
When fast reaches the end, slow is at the middle node. For list [1, 2, 3, 4, 5], the middle is node 3.

Why this problem matters

This is one of the simplest applications of the slow and fast pointer pattern. The same two-pointer setup appears in cycle detection (LeetCode 141), finding the cycle start (LeetCode 142), and checking if a linked list is a palindrome (LeetCode 234). If you learn this pattern here, those harder problems become much more approachable.

More importantly, finding the middle of a linked list is a subroutine in merge sort for linked lists. You split the list in half, sort each half recursively, and merge them. The "split in half" step is exactly this problem.

The approach

  1. Initialize two pointers, slow and fast, both starting at head.
  2. Move slow forward by one node and fast forward by two nodes on each iteration.
  3. When fast reaches the end of the list (either fast is null or fast.next is null), slow is sitting at the middle node.
  4. Return slow.

Why does fast move two steps? Because it covers the list at double speed. When fast finishes the entire list, slow has covered exactly half. That ratio is the whole trick.

The solution

def middleNode(head):
    slow = head
    fast = head

    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next

    return slow

Visual walkthrough

Let's trace through the list 1 -> 2 -> 3 -> 4 -> 5. Watch slow (amber) and fast (indigo) as they advance at different speeds.

Start: Both pointers at the head

12345slowfast

slow moves 1 step per turn. fast moves 2 steps per turn.

Step 1: slow moves to 2, fast moves to 3

12345slowfast

slow = node 2. fast = node 3. fast has not reached the end yet.

Step 2: slow moves to 3, fast moves to 5

12345slowfastmiddle

fast.next is null, so the loop stops. slow is at node 3. That is the middle.

After two iterations, fast has reached the last node (node 5) and fast.next is null. The loop exits, and slow is sitting at node 3. That is the middle.

For an even-length list like 1 -> 2 -> 3 -> 4 -> 5 -> 6, the same logic runs one extra step. When fast becomes null (it overshoots the end), slow is at node 4, which is the second of the two middle nodes. This matches the problem's requirement to return the second middle node.

Complexity analysis

MetricValue
TimeO(n)
SpaceO(1)

The fast pointer traverses the list once, making roughly n/2 iterations. Each iteration does constant work, so the total time is O(n). The space is O(1) because you only use two pointer variables regardless of the list size.

Building blocks

This problem is built from two core patterns.

Slow and fast pointers. Two pointers moving at different speeds through a linked list. The speed difference lets you extract structural information (the midpoint here, a cycle in other problems) without extra space. The fast pointer acts as a "scout" that tells you when to stop, while the slow pointer sits at the position you care about.

Linked list traversal. Walking through a linked list node by node using .next pointers. The loop condition while fast and fast.next is the standard guard for a pointer that moves two steps. You check both fast (to handle even-length lists where fast lands on null) and fast.next (to handle odd-length lists where fast lands on the last node).

Edge cases to watch for

  • Single node. fast is head and fast.next is null, so the loop body never runs. Return head. Correct.
  • Two nodes. After one step, slow is at the second node and fast is null. Return the second node. This matches the problem's rule of returning the second middle node for even-length lists.
  • Odd-length list. fast ends up at the last node. slow is at the exact center. No ambiguity.
  • Even-length list. fast overshoots to null. slow is at the second of the two middle nodes. This is the behavior the problem asks for.

From understanding to recall

The code for this problem is only five lines, but under pressure you might second-guess the loop condition or forget whether to return slow or slow.next. The best way to lock it in is to type it from scratch a few times with increasing gaps between sessions. After three or four reps, the pattern becomes automatic and you stop hesitating on the details.

Related posts