2Brute2Best
🔥0

Middle of the Linked List

Easy·LeetCode #876Basic Anchor
LeetCode
30-Second Mental ModelLinked List — Fast & Slow (middle)
Complexity:O(N)→O(N)
Key Insight

Start two pointers at the head. Each round, slow moves 1 step and fast moves 2 steps. Fast always has walked exactly twice as far as slow. So when fast runs out of list, slow is exactly halfway — the middle — in a single pass.

Core Validity Invariant

Fast is always twice as far from the head as slow, so the moment fast reaches the end, slow is at position n / 2 — the middle.

01

Problem

You are given the head of a singly linked list. Return the middle node of the list.

If the list has an even number of nodes, there are two middle nodes. Return the second one.

Return the node itself (the list from that node onward), not just its value.

Input

head, the first node of a singly linked list.

Output

The middle node. For an even length, the second of the two middle nodes.

Example 1
Input: head = [1, 2, 3, 4, 5]
Output: [3, 4, 5]

5 nodes, so the middle is the 3rd node (value 3). The answer is printed as the list starting from it.

Example 2
Input: head = [1, 2, 3, 4, 5, 6]
Output: [4, 5, 6]

6 nodes, so the two middles are 3 and 4. We return the second one, 4.

Constraints
  • • The list has between 1 and 100 nodes.
  • • 1 ≤ Node.val ≤ 100
02

First, think yourself

Before opening any solution, try to answer these on paper. Use hints only when stuck — each hint is counted.

  1. 1.

    In an array I would just return a[n / 2]. What stops me from doing that in a linked list?

  2. 2.

    Do I know the length of the list before I start walking?

  3. 3.

    If I counted the length first, how many steps from the head would the middle be?

  4. 4.

    Can two pointers moving at different speeds tell me when I am halfway?

  5. 5.

    For 6 nodes, should I stop on the 3rd node or the 4th? What about 5 nodes?

03

Brute force approach

04

Better approach

05

Optimized approach

06

Why does this algorithm work?

07

Dry run

08

All approaches compared

ApproachIdeaTimeSpace
Brute ForceStore every node pointer in a vector, return v[n/2]O(N)O(N)
BetterPass 1 counts n, pass 2 walks n/2 steps; no extra memoryO(N)O(1)
Optimalslow moves 1, fast moves 2; when fast hits the end, slow is the middleO(N)O(1)
09

Why does this belong to this pattern?

Clues in the problem statement
  • “middle node”We need the point halfway along a list whose length we don't know → one pointer at double speed.
  • “singly linked list”No indexes and no going back, so we can't jump to n / 2. We must find it while walking forward.
  • “two middles → return the second”This decides the loop condition: `fast && fast->next` stops on the second middle.
singly linked list+position defined by a fraction of the length (half)+one pass, O(1) space→Linked List — Fast & Slow (middle)

This is the anchor of the Middle / split sub-pattern. Fast moves 2, slow moves 1, so when fast reaches the end, slow is halfway. Unlike cycle detection, there is no loop here: fast does reach null, and the only question is where slow is when it does. The next questions use this exact loop as a first step: to cut the list in half (palindrome, twin sum) or to stop one node early (delete the middle).

10

Don't make this mistake

Returning the first middle on an even length
✗ while (fast->next != nullptr && fast->next->next != nullptr) { slow = slow->next; fast = fast->next->next; }
✓ while (fast != nullptr && fast->next != nullptr) { slow = slow->next; fast = fast->next->next; }

The "wrong" loop stops one round early on even lengths. On [1, 2, 3, 4, 5, 6] it returns 3, but this problem wants the second middle, 4. Both loops are useful — the first-middle version is what you want when splitting a list into two halves (see the next questions) — but read which middle the problem asks for.

Checking fast->next before fast
✗ while (fast->next != nullptr && fast != nullptr)
✓ while (fast != nullptr && fast->next != nullptr)

On an even length, fast jumps to null. The wrong order then reads fast->next on a null pointer and crashes. && checks left to right, so put the null check first.

Storing values instead of nodes
✗ vector<int> vals; ... return new ListNode(vals[n / 2]);
✓ vector<ListNode*> nodes; ... return nodes[n / 2];

The answer is the node that is already in the list, with the rest of the list after it. A new node with the same value has no next, so the output would be [3] instead of [3, 4, 5].

Using the cycle-detection loop
✗ slow = head; fast = head->next; while (slow != fast) { ... }

Pattern confusion: in cycle detection we wait for fast to meet slow. Here there is no cycle, so they never meet and fast runs off the end. For the middle, the stop signal is fast reaching the end, not fast catching slow. Also, starting fast one node ahead changes which middle you land on.

11

Want to implement this?

Write it yourself on LeetCode, then come back and compare your code with the solutions above.

Open coding workspace
How did it go?
Beyond The LeetCode Problem

How this concept connects to System Design & C++ Systems

Bridge DSA with production engineering

Top engineering interviews test whether you understand how algorithms like Linked List — Fast & Slow translate into production architectures and low-level memory mechanics.