Converging pointers on sorted arrays
Place one index at the start and one at the end. If the current pair is too small, move the left index right to increase the sum. If it is too large, move the right index left to decrease the sum. Sorting provides the monotonic relationship that makes each elimination safe.
def has_pair_with_sum(nums, target):
left, right = 0, len(nums) - 1
while left < right:
total = nums[left] + nums[right]
if total == target:
return True
if total < target:
left += 1
else:
right -= 1
return FalseThe scan takes O(n) time and O(1) extra space once the array is sorted. Sorting an unsorted input costs O(n log n) and may change the relationship between values and original indices; if original positions matter, store them before sorting.
Fast and slow pointers
In linked lists, a slow pointer can move one node while a fast pointer moves two. This detects cycles: in a cycle, the faster pointer gains one node per step on the slower pointer and eventually catches it. With arrays, fast/slow pointers can compact values in place: let the fast pointer scan every item and let the slow pointer mark the next write position.
For example, remove duplicates from a sorted array by copying each newly seen value to the slow position. This preserves the first occurrence and runs in linear time with constant extra memory.
Prove each move
Two pointers are not a magic replacement for nested loops. At every step, explain what all discarded candidates have in common. In the pair-sum example, when the sum is below the target, pairing the left value with any value to the right of the current right pointer would be even smaller. Therefore those candidates can all be eliminated together.
- Use converging pointers with sorted arrays, palindromes, and partitioning tasks.
- Use fast/slow pointers for cycle detection, middle-of-list discovery, and in-place filtering.
- Watch whether equal values should be skipped to avoid duplicate result combinations.
- Check whether sorting is allowed and whether the output must retain original order.
Rule of thumb: use two pointers when one pointer's movement lets you safely rule out a range of candidates.
Algo