Filter concepts by levelShowing all levels.

Algorithms · Two Pointers

Two Pointers

Two positions walking one structure — opposite ends, different speeds, or side by side

  • Opposite endsconverging on a sorted array in O(n)
  • Fast and slowFloyd's cycle detection in O(1) space
  • Merge, not re-sorttwo fronts, always take the smaller
  • Sorted is the signalpair/triplet on sorted input means try this first

1.Opposite-direction pointers (start/end converging)

Two pointers start at the two ends of a sorted array or string and move toward each other, comparing or combining the elements they point at — reversing, checking a palindrome, or finding a pair with a target sum, all in one O(n) pass.

Key features

  • Runs in O(n) time and O(1) extra space — no second array or reversed copy needed
  • Needs O(1) access to both ends — arrays, strings, and doubly linked lists qualify; a plain singly linked list cannot jump to its last element, so this pattern does not apply there directly
  • On a SORTED array: sum too small → move left inward (a bigger value); sum too big → move right inward (a smaller value)

On a sorted array: sum too small, move left inward; sum too big, move right inward — swapping that rule breaks the search entirely.

2.Same-direction pointers (fast/slow at different rates)

Two pointers both move forward through the same array — slow marks where the next kept value goes, fast scans ahead looking for one — letting you filter or compact an array in place, in one pass, with no second array.

Key features

  • fast always moves every step; slow only moves when something is actually kept — that gap is what compacts the array
  • This is the standard O(1)-extra-space technique behind "remove duplicates from a sorted array" and "move zeroes to the end"
  • It relies on the input already being sorted (or otherwise arranged so that what counts as "duplicate" or "keep" is adjacent) — see the mistake below

slow marks the last kept value, fast scans ahead — but this pattern only removes duplicates correctly when equal values are adjacent, which a sorted array guarantees and an unsorted one does not.

3.Fast/slow pointers for cycle detection (Floyd's algorithm)

Two pointers walk the same linked structure at different speeds — slow moves one step, fast moves two. If there is a cycle, fast eventually laps slow and they land on the same node; if there is no cycle, fast simply reaches the end first.

Key features

  • O(n) time, O(1) space — no set of visited nodes needed, unlike a hash-set approach to the same problem
  • fast moves 2 steps per iteration, slow moves 1 — once fast is inside the cycle, the gap between them shrinks by exactly 1 each round
  • Must check `fast and fast.next` before computing `fast.next.next` — skipping that check crashes on any non-cyclic list once fast reaches the end

fast moves two, slow moves one; check `fast and fast.next` before advancing fast, or a non-cyclic list crashes on None.next.

4.Merging two sorted structures with two pointers

To merge two already-sorted sequences into one sorted sequence, walk both with one pointer each and always take the smaller of the two current elements — O(n + m) total, with no re-sorting.

Key features

  • Never re-sorts anything — the O(n log n) cost of sorting each side happened earlier; merging only costs O(n + m)
  • When one pointer reaches the end of its sequence, the rest of the OTHER sequence is appended as-is — no comparisons needed
  • This exact idea is the 'merge' half of merge sort

Two pointers, one per sorted sequence, always advancing the one pointing at the smaller value — merging never needs to re-sort or compare against more than the two current fronts.

5.Three pointers (e.g. 3Sum built on top of two pointers)

Fix one element with a loop, then run the opposite-direction two-pointer scan on everything after it — turning a 3-variable search into a 1-variable loop wrapped around a 2-pointer scan.

Key features

  • Requires the array to be SORTED first — O(n log n) for the sort, then O(n²) overall (the fixed-index loop times the inner two-pointer scan)
  • Skipping repeats at i, left, AND right is what prevents duplicate triplets in the result, not just a final dedupe pass
  • The same 'fix one, two-pointer the rest' idea extends to 4Sum by fixing two indices instead of one

One fixed index plus a two-pointer scan on the rest turns 3Sum into the same O(n) inner pattern as Two Sum on a sorted array — sort first, and skip repeats at every one of the three positions.

6.Recognizing when a problem on a sorted array/list is a two-pointer problem in disguise

Whenever a problem gives a SORTED array or list and asks for a pair, triplet, or relationship between elements, try two pointers before anything more complex — sortedness is what lets pointer movement replace a nested loop.

Key features

  • The giveaway phrasing is "sorted array" or "sorted linked list" combined with "pair/triplet that satisfies X"
  • If the array is not sorted but a two-pointer-shaped answer would still work, check whether sorting it first is allowed — usually fine when only VALUES matter, not original positions
  • When original positions matter, sorting destroys that information — reach for a hash map instead (see algorithms.hashing-hash-maps-and-sets.trading-space-for-time)

Sorted + pair/triplet is the two-pointer signal — but only sort first if the answer needs VALUES, not original positions.

Remember

  • Sorted array, sum too small: move left inward. Sum too big: move right inward.
  • slow marks the last kept value; fast scans ahead — this only removes duplicates correctly on already-sorted input.
  • fast moves two, slow moves one for cycle detection — check `fast and fast.next` before advancing, or a non-cyclic list crashes.
  • 3Sum is one fixed index plus the same opposite-direction two-pointer scan, run once per index.

Pro tip

  • Merging two sorted sequences never re-sorts anything — it is the O(n + m) interleave step, the same one merge sort uses.
  • If a problem needs original positions preserved, sorting first is off the table — reach for a hash map instead.

Next up

  • Sliding Window
  • Recursion
  • Sorting Algorithms

Sources

  • Every example executed on Python 3.14.3 · checked 2026-09-14

Spotted a mistake on this page? Tell us.