Two Pointers: when to spot it, explain it, and practice it
Two pointers is the pattern for problems where relative movement matters more than remembering every previous state. It is especially strong when order, symmetry, or deduplication drives the answer.
Pattern coverage
60+
Best first move
Ask whether the pointers move in the same direction or opposite directions.
Common failure point
Moving the wrong side without a proof tied to ordering.
When this pattern should come to mind
Checklist before you code
The solving flow that works well in interviews
Write down what each pointer means before you move them.
Use the current comparison to prove which side can be safely discarded.
Move exactly one side unless the problem explicitly requires both.
Handle duplicates right where they would create repeated work or repeated answers.
Re-check the loop condition to avoid skipping the final valid pair.
Common variants
Opposite-direction
Great for sorted arrays, maximizing area, or converging on a target sum.
Fast/slow pointers
Useful for cycle detection, in-place filtering, and linked-list traversal.
Partition pointers
Useful when elements need to be grouped by a predicate or pivot.
Template preview
# Opposite-direction pointers on a sorted array
left, right = 0, len(nums) - 1
while left < right:
if good(nums[left], nums[right]):
return answer
if should_move_left(nums[left], nums[right]):
left += 1
else:
right -= 1
# Fast/slow pointers
slow = 0
for fast in range(len(nums)):
if keep(nums[fast]):
nums[slow] = nums[fast]
slow += 1
Classic problems with useful framing
#11
Container With Most Water
Teaches the proof for moving the shorter side.
Pick two lines that form the container with maximum area.
#15
3Sum
Covers sorting, deduplication, and inner pointer control.
Return all unique triplets whose sum is zero.
#42
Trapping Rain Water
Shows how local bounds lead pointer movement.
Compute how much rain water can be trapped between bars.
#287
Find the Duplicate Number
Introduces fast/slow pointers on implicit linked structures.
Find the duplicate number in an array of n + 1 integers.
A more useful problem ladder for practice
This is not a random list. It is ordered to help candidates build recognition first, add key variants next, and then increase pressure with harder cases.
Foundation
#1 Two Sum
Find two indices whose values add up to the target.
You are really solving a complement query: for each value x, ask whether target - x has appeared already.
Foundation
#11 Container With Most Water
Pick two lines that form the container with maximum area.
Moving the taller side cannot help because width shrinks and the shorter wall still limits height.
Variant depth
#15 3Sum
Return all unique triplets whose sum is zero.
Once the array is sorted, the remaining two numbers must move based on whether the current sum is too small or too large.
Variant depth
#31 Next Permutation
Transform the array into the next lexicographically larger permutation.
The suffix after the pivot is descending, which is why the next larger element and final reversal can both be found efficiently.
Pressure test
#54 Spiral Matrix
Return the elements of a matrix in spiral order.
After traversing one side, you must immediately tighten the corresponding boundary before moving to the next side, otherwise elements get duplicated or skipped.
Pressure test
#146 LRU Cache
Design an LRU cache with O(1) get and put.
The list stores recency order, while the hash map gives O(1) access to the node that must be moved.
High-frequency mistakes
Moving the wrong side without a proof tied to ordering.
Forgetting duplicate skipping in 3Sum-style problems.
Using two pointers where a hash map is actually cleaner.
Missing edge cases around equal elements and pointer crossing.
Recommended practice path
Start with Two Sum II and Container With Most Water.
Then solve 3Sum and deduplication-heavy array problems.
Add linked-list fast/slow pointer questions afterward.
Finish with harder partition and cycle-detection hybrids.