On sorted data, position is information: one finger at each end, and every comparison proves a whole batch of candidate pairs innocent. One skeleton, five costumes — and the O(n²) inner loop quietly disappears.
Chapter 4's hash map bought speed with memory: pay O(n) space and "have I seen this?" becomes free. This chapter's trick costs nothing — if the data is sorted, its positions already answer questions. Two index fingers, one at each end, walking toward each other: that's the whole pattern, and it kills quadratic loops for pair sums, palindromes, water containers, and 3Sum.
The skill to take from this chapter is a single sentence — the discard argument — that justifies every pointer move. Say it out loud in an interview and you've demonstrated the exact "reasons about invariants" signal Chapter 1 said they're buying.
Meet Two Sum II Medium: same deal as Chapter 4's Two Sum — find two numbers that hit a target — except the array arrives sorted, and the problem demands O(1) extra space. That second clause is the problem legally forbidding the hash map. It's not being cruel; it's steering you to the better tool.
The tool: plant l = 0 on the smallest value and r = n − 1 on the largest. Look at a[l] + a[r]:
Loop while l < r. Each step moves exactly one pointer inward, so the walk takes at most n − 1 steps: O(n) — one pass, no allocations, no map. The mystery worth a section of its own: why is it safe to move a pointer and never look back?
Ten elements have 45 possible pairs. Brute force interrogates all 45. The converging walk asks at most 9 questions — so each question must be eliminating batches of pairs, not just the one it looked at. Here's the argument, and it's the sentence to say out loud in the room:
"If a[l] + a[r] < target, then a[l] just failed with the biggest partner it will ever get. Failing with your best partner means failing with everyone — a[l] cannot appear in any answer. Retire it."
Symmetrically, when the sum overshoots, a[r] just overshot with the smallest partner still available, so it's out. One comparison, and every pair involving the retired element is ruled out at once — a whole row of the pair table gone. That's the entire reason sortedness matters: it makes the ends extreme, and extremes make one test speak for many.
Drag the pointers below anywhere you like — the explainer will tell you which move the algorithm would force, and why. Watch the "pairs ruled out" counter: it's doing 45 pairs of work in single-digit moves.
Swap the question from sum to compare and the same skeleton solves Valid Palindrome Easy — the warm-up interviewers reach for when they want you talking within two minutes. A string reads the same backward exactly when every mirrored pair of characters matches, and the two fingers are the mirror: compare s[l] with s[r], step both inward, first mismatch ends it.
The interview version adds grit: "ignore non-alphanumeric characters and case." That's two tiny inner loops — while s[l] isn't alphanumeric, l++; same on the right — then lowercase both and compare. Each character is still visited once, so it stays O(n) with O(1) space, which is the entire point: the "reverse the string and compare" one-liner also works but silently spends O(n) memory, and a good interviewer will ask you why.
The follow-up they love: Valid Palindrome II — "you may delete at most one character." At the first mismatch you get a fork: skip the left char or skip the right char, and check if either remaining slice is a clean palindrome. Two extra walks, still linear. Note the shape: the pattern didn't change, the question at the fingertips did.
Container With Most Water Medium: vertical walls of given heights; pick two that hold the most water. Area = min(h[l], h[r]) × (r − l) — the shorter wall sets the ceiling. Brute force tries all pairs, O(n²) — "for each wall, try every other wall". The two-pointer version starts at maximum width and walks inward in O(n), with one rule: always retire the shorter wall.
Why is that safe? The discard argument again, in greedy clothing. Once the pointers start moving inward, width only shrinks. So consider the shorter wall: every container it could form from here on is narrower than the current one, and its ceiling can never rise above the short wall itself. The current area is therefore the best that wall will ever do — it has peaked, on camera, and can be retired without regret. The taller wall still has upside (a taller partner might appear), so it stays.
Note what this is: a greedy choice with a one-sentence proof. Chapter 19 makes a whole chapter of that move — and of the disasters that follow when the sentence doesn't actually hold.
3Sum Medium is the pattern's most famous costume: find all unique triples summing to zero. The leap from pair to triple is one sentence: fix an anchor, and the rest is a pair problem you already solved. Sort once — O(n log n), sort once then walk — then for each anchor a[i], run Section 1's converging walk on the suffix i+1 … n−1 hunting a pair that sums to −a[i].
Cost: n anchors × an O(n) walk = O(n²), and the sort disappears into the noise. Two free accelerations fall out of sortedness: the anchor only needs to run while a[i] ≤ 0 (three positives can't sum to zero — once anchors go positive, stop the whole search), and the walk only ever looks rightward of the anchor, so no triple is examined twice.
Could you use Chapter 4's hash map for the inner pair instead? Yes — and interviewers watch candidates try, because the follow-up "…all unique triples" turns the hash version into a swamp of tuple-canonicalization. The sorted walk dedups almost for free, which is the next section. This is why 3Sum is beloved as an interview stage: it tests whether you can compose two patterns and handle the seam.
Sorted duplicates sit next to each other, so skipping them is a pointer hop, not a set lookup. The dance has exactly three moves:
Why only after a record? Because ordinary comparisons already slide over duplicate runs harmlessly — a repeated value just fails the same comparison again and moves on. Duplicate output is only ever born at the moment of success: same anchor re-run, or the same (second, third) pair rediscovered one slot over. Guard the successes and the output is clean.
Step the real algorithm below, then flip dedup off and run it again — same array, same walk, and watch the output fill with clones.
Not all two-pointer walks converge. The pattern's other body plan puts both pointers at the start, moving the same way, with different jobs: read scans every element; write marks the end of the kept prefix. The invariant to say out loud: everything left of write is the answer so far. When read finds a keeper, copy it to write and advance both; otherwise only read moves. One pass, in place, nothing allocated.
That's the whole solution to Remove Duplicates from Sorted Array Easy (keep an element when it differs from its left neighbor) and Move Zeroes Easy (keep non-zeros, then zero-fill the tail). The problems feel like deletion; the pattern reframes them as compaction — you never delete, you overwrite forgettable things with keepable things.
File the shape carefully, because Chapter 6 is its glow-up: a sliding window is two same-direction pointers plus state maintained between them. Learn the read/write pair today and the caterpillar tomorrow is just this plus a bookkeeping map.
Every problem in this chapter is the same skeleton wearing a different question at the fingertips:
And one preview from the boss room: Trapping Rain Water Hard. Water above cell i is min(maxLeft, maxRight) − h[i] — and a converging walk can carry both running maxes, moving the side with the smaller max, because that side's water level is already decided by its own max. It's this chapter's discard argument playing in the rain. (Chapter 8's monotonic stack will claim the same problem — good problems have shared custody.)
The pattern, as a whiteboard skeleton:
The flagship, in full: sort, anchor loop with the positive-anchor early exit, the converging walk from Section 1, and all three moves of the dedup dance. Read it as three stacked patterns — the sort buys the discard argument, the anchor buys the third dimension, the skips buy uniqueness. This is the version to reproduce on a whiteboard; every line has a spoken sentence attached.
Flip the tabs: the Scala version keeps the same imperative skeleton on purpose — two pointers is the rare pattern where the mutable walk is the idiom, and dressing it in folds obscures the invariant you're being paid to narrate. The delta worth memorizing is small: anchor loop, walk, three skips. Everything else is 3Sum-specific color.