Two Pointers¶
Also known as: Opposite-Direction Pointers, Converging Pointers, Left-Right Pointers
Two indices walk the array — usually from both ends toward each other, or one behind the other. Because each pointer only ever moves in one direction, the whole array is covered in a single pass with no extra memory. On sorted data, comparing the two ends tells you which pointer to move, so you discard half the useless comparisons for free.
Before you start¶
- Comfortable using a basic loop and indexing into an array in your language.- Frequency Counter (the hash-map approach is the baseline this pattern improves on)
What 'solved properly' looks like
Target: O(n) time, O(1) space. If your solution is slower than that, you've found a solution but not this pattern — the judge says "Accepted" either way, so treat this as your real benchmark.
The idea¶
You place one pointer at the start of the array and another at the end, then move them toward each other based on a condition. Because the data is sorted (or you sort it first), comparing the two ends gives you information about the middle — every time you move a pointer, you eliminate one element from further consideration without ever revisiting it. The same idea works with both pointers starting at the same end, one lagging behind the other, for problems that need in-place removal or deduplication.
Why it matters: It's the O(1)-space answer to problems where a hash map would work but cost memory, and it's the foundation of the sliding window pattern (which is just two pointers moving the same direction). If you can recognise when the data gives you ordering for free — a sorted array, a palindrome check, an in-place swap — you skip the hash map entirely and solve in constant space.
When to reach for it¶
Reach for it when you see a sorted array and need to find a pair that satisfies a condition, check whether a string is a palindrome, reverse or swap elements in place, remove duplicates without allocating extra space, or partition an array. The phrase "without extra space" or "in-place" is a strong tell — especially when the obvious approach would use a hash map or a second array.
When not to use it
The pair-search variant needs sorted data. If the array isn't sorted, the two-pointer approach simply doesn't work — you'll either miss valid pairs or need to sort first (which costs O(n log n)), and at that point a frequency counter (O(n) time, O(n) space) may be the better trade-off. Pick deliberately, not by reflex. Also: don't confuse this with sliding window. In sliding window, both pointers move the same direction and the region between them is what matters — the window itself is the unit of work, not the elements at the pointers.
Practice set¶
Work these top to bottom. The time-box is a cue to pause and re-read the triggers above if you're still stuck when it passes — not a deadline to race. Getting unstuck by stepping back is the skill being trained.
| # | Problem | Where | Difficulty | Time-box | Role |
|---|---|---|---|---|---|
| 1 | Valid Palindrome | LeetCode | Easy | 15 mins | teaching |
| 2 | Move Zeroes | LeetCode | Easy | 15 mins | teaching |
| 3 | Two Sum II — Input Array Is Sorted | LeetCode | Medium | 20 mins | consolidation |
| 4 | Remove Duplicates from Sorted Array | LeetCode | Easy | 20 mins | consolidation |
| 5 | 3Sum | LeetCode | Medium | 40 mins | challenge |
Already know this? Test out.
If you can solve 3Sum cleanly in one sitting — handling the duplicate-skipping logic without a hint — you already own this pattern, so move on to the next one. If it tangles you up, that's your signal to work the set from the top instead of skipping.