Module F-8·16 min read

Converging and fast/slow pointer patterns that turn O(n²) nested loops into O(n) passes.

JJS
Written by Jatin Jain Saraf · Senior Software Engineer

Module F-8 — Two-Pointer Technique

What this module covers: Two pointers walking through the same data — either converging toward each other or moving at different speeds — turn a surprising number of O(n²) problems into O(n). You've already seen fragments of this pattern: array reversal and palindrome checking in Modules F-2 and F-3, and the head/tail pointers behind an efficient queue in Module F-7. This module names the pattern directly and generalizes it.


Converging Pointers

The shape: one pointer starts at the left end, one starts at the right end, and they move toward each other, each step ruling out one element from further consideration.

Two Sum on a sorted array is the cleanest illustration, and it's worth contrasting directly with the hash map version from Module F-4:

typescript

This works because the array is sorted: if the current pair sums too small, moving right inward can only make the sum smaller too (or equal) — the only direction that can help is increasing left. That single fact lets each pointer move only inward, never backward, so the two pointers together make at most n total steps — O(n), and critically, O(1) extra space, unlike Module F-4's hash-map version, which trades O(n) space for not needing the array sorted in the first place. This is a genuine trade-off, not a strictly better algorithm: sort cost (O(n log n), Modules P-9/P-10) versus hash map space, depending on what you're given and what you can afford.

Container With Most Water — given a set of vertical lines, find the two that trap the most water between them — uses the same converging shape, but the "which pointer moves" rule is different:

typescript

The reasoning that justifies moving the shorter side is worth sitting with: the water trapped between any two lines is capped by the shorter one, regardless of how tall the other is. Keeping the taller line and discarding the shorter one can never produce a better answer than what you've already measured — every option that keeps that shorter line is strictly worse or equal, so it's always safe to move past it. This is what makes the two-pointer approach O(n) instead of checking every pair — O(n²).

Sort Colors (the Dutch national flag problem) is a three-way partition using three pointers instead of two, in a single left-to-right pass:

typescript

low tracks the boundary of confirmed 0s, high tracks the boundary of confirmed 2s, and mid scans forward — one pass, O(n) time, O(1) space, no separate counting step. This exact three-way-partition shape is also the core of quicksort's partitioning step, covered in full in Module P-10.


Fast/Slow Pointers

Sign in to keep reading

The rest of this module is free — sign in with Google to unlock it and track your progress.

Sign in & Register

Discussion

0

Join the discussion

Loading comments...

© 2026 Jatin Jain Saraf (JJS). All rights reserved.