The Core Idea
Two Positions Moving Through the Same Data
The two-pointer technique uses two index variables that move through an array (usually sorted) according to a rule, instead of using nested loops to compare every element to every other element. Where a brute-force pair-check is O(n²), a well-designed two-pointer pass is O(n) ā because each pointer only moves forward, never backward, and together they cover the array in a single combined pass.
This works because sorted (or otherwise structured) data lets you make a guarantee: if the current pair doesn't work, you know with certainty which pointer to move ā you don't need to re-check combinations you've already ruled out.
š” Memory Trick
Picture two people at opposite ends of a sorted line of numbered boxes, walking toward each other. If their combined total is too small, the person on the left steps in (bigger numbers are further right). If it's too big, the person on the right steps in (smaller numbers are further left). They meet in the middle having checked every useful combination exactly once ā no repeats, no wasted steps.
The Two Patterns
Opposite-Direction vs. Same-Direction Pointers
1
Opposite-Direction Pointers
One pointer starts at index 0 (left), the other at the last index (right). They move toward each other based on a comparison rule, until they meet or cross. This pattern is the classic solution for 'find two numbers in a sorted array that sum to a target.'
Example: in a sorted array, if left+right sum is too high, move right pointer left; if too low, move left pointer right.
2
Same-Direction Pointers (Sliding Window)
Both pointers start near the beginning and move forward, with one (the 'fast' or trailing edge) usually staying ahead of the other. This forms a 'window' over a contiguous section of the array that expands or shrinks as it slides, commonly used for problems about subarrays or substrings meeting some condition.
Example: finding the longest substring without repeating characters by expanding the window's right edge and shrinking the left edge when a repeat is found.
The Complexity Win
From O(n²) Nested Loops to O(n) Single Pass
A naive solution to 'find two numbers that sum to a target' checks every pair with nested loops ā for each element, scan every other element, which is O(n²). The two-pointer version, run on sorted data, moves each pointer at most n times total across the whole algorithm, giving O(n) ā plus the one-time cost of sorting if the data wasn't already sorted, which is O(n log n).
This pattern generalizes well beyond arrays ā it's used in merging two sorted lists, removing duplicates in place, partitioning arrays (as in quicksort), and reversing arrays or strings in place without extra memory.
š„ļø Applied Scenario
You're given a sorted array of prices and need to find two prices that add up exactly to a customer's $50 gift card balance.
1
You set left = 0 (cheapest price) and right = last index (most expensive price), and check their sum.
2
If the sum is less than $50, you know you need a bigger number, so you move left forward one position (since the array is sorted, this only increases the sum).
3
If the sum is more than $50, you move right backward one position to decrease the sum.
4
Conclusion: you repeat until the sum equals $50 or the pointers cross, solving the problem in a single O(n) pass instead of checking every possible pair in O(n²).
š Exam Application
Exam questions often present a brute-force nested-loop solution and ask you to optimize it, expecting you to recognize when the two-pointer pattern applies ā the signal is usually sorted data (or data you're allowed to sort) plus a need to find a pair, triplet, or subarray meeting some sum or condition. You may also be asked to identify whether a problem needs opposite-direction pointers or a sliding window.
ā ļø Most Common Two-Pointer Technique Mistakes
The most common mistake is applying the opposite-direction pattern to unsorted data without sorting first ā the 'move left if sum too small' logic only works because sorting guarantees direction of change. Another frequent error in sliding-window problems is forgetting to shrink the window from the left when the condition is violated, which causes the window to grow indefinitely instead of correctly tracking the valid range.
ā Quick Self-Test
Can you explain why the two-pointer technique requires sorted data for the opposite-direction pattern, but not necessarily for the sliding-window pattern? Can you trace through finding a pair that sums to a target in a small sorted array, writing down left and right at each step?
Next Lesson
Divide and Conquer
ā
ā All Algorithms Lessons