Two pointers

Updated October 7, 2026 · By the Devana Team

Two pointers walks two indexes through a sequence at the same time, either from both ends toward the middle or one fast and one slow, so every step rules out part of the input instead of checking every pair. On sorted data, or when you rearrange an array in place, it turns an O(n squared) search into one O(n) pass with O(1) extra memory.

Pattern 2 of 16 in coding patterns · Foundations

When to reach for it

  • The input is sorted, or you may sort it, and you need a pair or triple that meets a condition.
  • You compare the start and end of something: palindromes, mirrored sequences, reversing in place.
  • You must filter or rearrange an array in place with constant extra space.
  • You walk two sorted sequences side by side: merging, diffing, finding common items.

The core idea

Each pointer marks an edge of the part of the input you still need to consider. Because the data is ordered, comparing the values under the two pointers tells you which side cannot be part of any answer, so you move that pointer and never look back. That one-way movement is why the whole pass costs O(n).

There are two shapes. Opposite ends: left starts at the first index and right at the last, and they move toward each other until they meet. Same direction: a slow pointer marks where the next kept element goes while a fast pointer scans ahead; everything before slow is finished output. Diffing two sorted lists is the same idea with one pointer in each list.

A Python template

def pair_with_sum_sorted(nums, target):
    left, right = 0, len(nums) - 1
    while left < right:
        total = nums[left] + nums[right]
        if total == target:
            return left, right
        if total < target:
            left += 1          # too small: nothing pairs with nums[left]
        else:
            right -= 1         # too big: nothing pairs with nums[right]
    return None

def keep_in_place(nums, keep):
    """Move every element that passes keep() to the front, in order."""
    slow = 0
    for fast in range(len(nums)):
        if keep(nums[fast]):
            nums[slow] = nums[fast]
            slow += 1
    return slow                # length of the kept prefix

def common_sorted(a, b):
    i = j = 0
    out = []
    while i < len(a) and j < len(b):
        if a[i] == b[j]:
            out.append(a[i]); i += 1; j += 1
        elif a[i] < b[j]:
            i += 1             # a[i] is too small to appear in b
        else:
            j += 1
    return out

Time and space

Each pointer moves in one direction only, so together they take at most n steps: O(n) time and O(1) extra space. If you sort first, the sort dominates at O(n log n). For triples, fix one element and run the pair search on the rest, which is O(n squared) overall: still a full factor of n better than three nested loops.

Common mistakes

  • Running the opposite-ends version on unsorted data, where moving a pointer can skip the answer.
  • Looping with left <= right when an element must not pair with itself.
  • Forgetting to skip equal neighbors when the question wants unique triples, which reports the same answer several times.
  • Returning indexes from a sorted copy when the question wants positions in the original array.
  • Writing to slow before reading fast in a way that overwrites a value you have not moved yet.

How to explain it out loud

Say why a pointer may move, because that sentence is the proof that the algorithm is correct: "The array is sorted, so if the sum is too small, nothing can pair with the left value. I can drop it." Interviewers wait for it, and Devana's rubric scores it as logic explanation.

Before coding, state what is true about the data between or before your pointers. After coding, trace a short example with both pointers moving, then name the duplicate, empty and single-element cases and give O(n) time with O(1) space. Saying all of this unprompted is the difference between thinking out loud and answering questions when asked.

Practice questions

These come from Devana's question bank, in the order to try them. Each one starts a voice mock interview with Josh, Devana's AI interviewer, on that question, so you practice explaining the approach out loud as well as getting it right.

  • Valid Palindrome

    easyOpposite ends, skipping characters that do not count.

    Practice
  • Diff two enormous sorted indexes

    mediumGoogle · One pointer per sorted stream, O(1) memory.

    Practice
  • Reverse the word order in a text buffer

    mediumMicrosoft · In-place reversal with careful whitespace handling.

    Practice
  • Three Sum

    mediumFix one value, then a pair search, skipping duplicates.

    Practice
  • Container With Most Water

    mediumDeciding which side to move from the comparison.

    Practice

Prove it in a mock interview

A 15-minute mock interview on a question that is not on the practice list, scored out of 100. Score 70 or more and two pointers is marked proven on your roadmap. It counts as one of your interviews: the Free plan has 3 a month, no card needed.