Course outline · 0% complete

0/30 lessons0%

Course overview →

Two pointers

lesson 4-1 · ~13 min · 10/30

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 is lo += 1 (everything left of hi paired with nums[lo] would be even smaller, so nums[lo] is dead, discard it).
  • If it is too big, shrink with hi -= 1 for 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.

sorted, so each comparison retires one end1346811lohisum too small: lo moves right · sum too big: hi moves left
Two pointers on a sorted array. The pair (nums[lo], nums[hi]) is the current guess, and each comparison discards one end for good.

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.

  • read visits every element.
  • write marks the boundary: everything left of it is finished output.
  • When read finds an element worth keeping, copy it to position write and advance write.

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.