Intuition First: Closing In From Both Ends#

Picture a long shelf of books arranged by price, and you want two of them that together cost exactly ₹500. One friend starts at the cheap end, another at the expensive end. If their two books total too much, the friend at the expensive end steps inward to something cheaper. If it's too little, the cheap-end friend steps up to something pricier. They keep walking toward each other until the prices add up, or they meet in the middle and give up.

Because the shelf is sorted, every single step rules out a whole range of pairs at once. That's the whole trick: a check-every-pair search that would take O(N²) collapses into one inward walk of O(N).


The Core Idea#

Two Pointers is a technique, not a single algorithm. You maintain two index variables, left and right, and move them toward each other (or in the same direction) to avoid nested loops.

Instead of O(N²) brute force, you get O(N) by exploiting the structure of the data.


The Classic Problem: Pair Sum in a Sorted Array#

Given a sorted array and a target sum, find two indices whose values add up to the target.

text

Because the array is sorted, we can make intelligent decisions:

  • Sum too large → shrink from the right (move right left)
  • Sum too small → grow from the left (move left right)
  • Time Complexity: O(N), since each pointer moves at most N steps total
  • Space Complexity: O(1), just two index variables

Interactive Lab#

Let's take the example in the visualization below: the sorted array [2, 5, 8, 13, 21, 34, 55, 89, 144] and a target sum of 21. Note that the target here is a sum of two values, not a value to locate.

Play it and watch the asymmetry. left sits still on 2 while right walks inward five times (2 + 144, 2 + 89, 2 + 55, 2 + 34, 2 + 21, all overshooting 21). Only once 2 + 13 = 15 undershoots does left start moving, and two steps later the pointers land on 8 + 13 = 21 and both turn green.

Eight comparisons instead of the 36 pairs a nested loop would test, and every dimmed cell is a pair the sortedness let us rule out without ever evaluating it.


Other Two-Pointer Patterns#

Same-Direction (Fast & Slow)#

Used for problems like "remove duplicates" or cycle detection in linked lists.

Python

Partition (used in Quick Sort)#

One pointer from the left finds a large element; one from the right finds a small element. They swap until they cross.

Converging on a String: Palindrome Check#

The same inward walk works on characters. A palindrome reads identically in both directions, which is exactly the statement "the character at left equals the character at right, all the way in."

Let's take the example in the visualization below: the word RACECAR. Play it and count the comparisons. There are only three:

text

Watch what the pointers never do: they never touch the middle E. Once left and right land on the same index there is nothing left to pair it with, so the loop exits and the odd-length centre is answered for free. Seven characters, three comparisons: ⌊n/2⌋, not n.

A mismatch would stop it dead on the spot. Nothing after the first disagreeing pair matters, which is why this is O(N) with an early exit rather than a full scan.


When to Reach for Two Pointers#

SignalUse Two Pointers?
Sorted array + pair/triplet sum✓ Yes
Remove duplicates in-place✓ Yes
Palindrome check✓ Yes
Unsorted array + exact pair✗ Use hash map instead

What to Remember#

Two Pointers replaces a nested loop (O(N²)) with two synchronized pointers (O(N)) whenever the data has enough structure to tell you which pointer to move. Sorting the array first, even at O(N log N), is often worth it because the two-pointer pass saves more.