Quiz
Warm-up from lesson 3-3: you learned the sort-then-solve pattern. What does sorting buy you for a "find a pair" problem?
Two pointers
A pointer here is just an index variable. The two-pointer pattern keeps two of them, usually lo at the start and hi at the end, and moves them toward each other based on what they see.
Take pair-sum on a sorted list: does any pair add to target?
- If
nums[lo] + nums[hi]is too small, the only way to grow the sum islo += 1(everything left ofhipaired withnums[lo]would be even smaller, sonums[lo]is dead, discard it). - If it is too big, shrink with
hi -= 1for the mirror reason. - Equal? Found it.
Every step permanently retires one element, so the whole scan is O(n) time, O(1) space. Compare that with lesson 1-1: the set solution was O(n) time but O(n) space. Sortedness bought us the memory back.
Code exercise · python
Run this. The trace shows both pointers and the current sum. Only two comparisons are needed to find 3 + 11 = 14 in this six-element list.
Code exercise · python
Your turn. A palindrome reads the same forwards and backwards. Write is_palindrome(s) with two pointers: compare s[lo] and s[hi], move both inward, and return False on the first mismatch.
Quiz
In pair_sum_sorted, the sum is too SMALL. Why is it safe to discard nums[lo] forever?
Same-direction pointers: reader and writer
Converging lo/hi pointers are half the pattern. The other half moves two pointers the same direction at different speeds, usually named read and write. The reason this variant exists: many problems demand you edit a list in place — O(1) extra space, no second list — and one index cannot both scan the input and mark where the cleaned-up output ends.
readvisits every element.writemarks the boundary: everything left of it is finished output.- When
readfinds an element worth keeping, copy it to positionwriteand advancewrite.
One pass, O(n) time, O(1) space. Remove-duplicates-from-sorted-array, move-zeros, and remove-element are all this exact loop with a different "worth keeping" test.
Code exercise · python
Run this. move_zeros copies every non-zero forward to the write boundary (preserving their order), then fills the tail with zeros — all in place, no second list.