Two pointers are useful when moving one boundary changes the result monotonically. The pattern is not “put two variables in a loop”; the movement must let us prove that discarded candidates cannot be better.
3Sum Closest
Sort the array, fix one value, then move two pointers through the remaining range.
1 | def three_sum_closest(numbers, target) |
Sorting costs O(n log n) and the nested scan costs O(n²), so total time is O(n²). Using sort instead of sort! avoids mutating the caller’s array as a surprise bonus feature.
Container With Most Water
1 | def max_area(heights) |
The shorter wall limits the area. Moving the taller wall inward only reduces width while keeping the same limiting wall, so it cannot improve the result. We move the shorter wall because only a taller replacement can compensate for the lost width.
- Time complexity:
O(n). - Extra space:
O(1).
That proof is the pattern. The pointers are merely its employees.