The fast and slow pointers pattern is a core interview technique used when you need to reason about positions, cycles, or relative movement in a sequence, most commonly linked lists, but also arrays and number sequences. The idea is simple but powerful. You move two pointers through the structure at different speeds, usually one step at a time for the slow pointer and two steps at a time for the fast pointer. The difference in speed allows you to uncover properties of the data without extra memory.
For interview preparation, this pattern is especially valuable because it replaces brute-force approaches that use hash sets or extra storage with O(1) space solutions. If a problem involves detecting cycles, finding a midpoint, or determining whether something eventually repeats, fast and slow pointers are often the intended solution. Many problems that initially feel tricky become straightforward once you recognize that relative motion can give you the answer.
Core intuition
The power of this pattern comes from relative speed. Because one pointer moves faster than the other, their positions tell you something meaningful about the structure:
- If there is a cycle, the fast pointer will eventually lap the slow pointer and meet it.
- If there is no cycle, the fast pointer will reach the end first.
- If you want the middle, letting one pointer move twice as fast guarantees that when the fast pointer reaches the end, the slow pointer is halfway.
Instead of tracking visited elements, you let motion itself reveal structure.
General algorithm
The typical structure looks like this:
- Initialize both pointers at a point
- Move slow by one step
- Move fast by two steps
- Check conditions (meeting, reaching end, etc.)
- Stop when the problem’s condition is satisfied
The exact stopping logic depends on the problem, but the movement pattern stays consistent.
Common variants
Common real-world applications of the fast and slow pointers pattern include detecting cycles, finding the middle of a list, checking for palindromes, and identifying cycles in number transformations such as the Happy Number problem.
Linked List Cycle (Floyd’s Cycle Detection)
This is the most well-known application of the fast and slow pointers pattern. Both pointers start at the head of the linked list, with the slow pointer moving one step at a time and the fast pointer moving two steps at a time. If the list contains a cycle, the fast pointer will eventually lap the slow pointer and they will meet inside the loop. If, instead, the fast pointer reaches null, the list has no cycle. This same idea can be extended beyond simple detection: once the pointers meet, you can use additional pointer movement to determine the starting node of the cycle and even calculate the length of the cycle.
Middle of the Linked List
In this variant, the slow pointer moves one step at a time while the fast pointer moves two. When the fast pointer reaches the end of the list (or can no longer move two steps), the slow pointer will be positioned at the middle. This works because the slow pointer travels half as far as the fast one. For even-length lists, the slow pointer typically ends at the second middle node, depending on how the loop condition is written. This approach avoids the need to first count the number of nodes or compute the list’s length.
Palindrome Linked List
Fast and slow pointers are also useful when checking whether a linked list is a palindrome. The pointers are first used to find the middle of the list. From there, the second half of the list can be reversed in place, and the two halves can be compared node by node. This approach allows you to determine whether the list reads the same forwards and backwards using O(1) extra space, which is often a key constraint in interview problems.
Happy Number
Some problems define a transformation on a number or value, such as repeatedly replacing a number with the sum of the squares of its digits, and ask whether the sequence eventually reaches a known value or loops forever. Instead of storing all previously seen values in a set, you can treat each generated value as a “node” in an implicit linked list. By advancing one pointer one step at a time and another two steps at a time, you can detect whether the sequence enters a cycle. This reframes what looks like a math problem into a standard cycle detection problem.
Time and space complexity
Time complexity is O(n) because even though the fast pointer moves at twice the speed of the slow pointer, both pointers are still limited by how many nodes/elements exist. In the worst case, the fast pointer reaches the end (no cycle) or the two pointers meet (cycle) after a linear number of steps. So overall, the total work grows proportionally with the size of the input.
Space complexity is O(1) because the algorithm only uses a constant number of pointers, regardless of input size.
There are no extra data structures like hash sets or arrays to store visited elements. This combination of linear time and constant space is a big reason interviewers like the pattern so much.
How to spot it in interviews
Reach for fast and slow pointers when the problem is really about relative position or repetition in a sequence, especially when you don’t know the length upfront and you’re expected to use O(1) extra space.
This pattern is a strong fit when:
- You’re working with a linked list and need the middle, a cycle, a cycle start, or an intersection-style insight.
- The prompt includes words like cycle, loop, circular, repeating, eventually, or meet.
- You feel tempted to use a set/map to track visited nodes/states, but space is constrained or “O(1) extra space” is implied.
- You’re dealing with a repeated-state process (numbers, index jumps, transformations) that can be treated like an implicit linked list.
Quick interview check. Ask yourself:
- “Do I need to detect repetition or a loop?”
- “Am I tempted to store visited states?”
- “Do I need the middle or some relative position without knowing the length?”
If you say “yes” to any of these, fast and slow pointers should be one of your first approaches.
Common pitfalls
- Forgetting to check
fastandfast.nextbefore advancing (null pointer errors). - Assuming a cycle always exists without handling the no-cycle case.
- Moving pointers incorrectly (e.g., both moving one step).
- Overcomplicating the solution when relative motion already gives the answer.