Module F-11·16 min read

O(log n) search and its variants — first/last occurrence, rotated arrays, and peak finding.

JJS
Written by Jatin Jain Saraf · Senior Software Engineer

Module F-11 — Binary Search and Its Variants

What this module covers: Every search technique so far in Foundation has been O(n) — a full scan, a two-pointer sweep, a sliding window. This module introduces the first O(log n) technique: binary search, which works whenever data is sorted (or has an equivalent monotonic property), and its variants — finding boundaries, searching rotated data, and finding a peak — that all reuse the same halving idea.


The Core Idea: Halving, Not Scanning

Binary search works on sorted data by repeatedly checking the middle element and discarding the half of the search space that can't contain the answer:

typescript

Each comparison eliminates half of whatever's left, not just one element. Starting from n elements, after one comparison there are n/2 candidates left, then n/4, then n/8 — the number of halvings needed to get down to a single candidate is log₂(n). At a million elements, that's roughly 20 comparisons — not a million, not even a thousand. This is the O(log n) complexity class from Module F-1's table, made concrete.

Analogy: Binary search is how you actually look up a name in a phone book (if you've ever seen one) or find a word in a physical dictionary — you don't start at page 1. You open to the middle, see you've overshot or undershot, and repeat on the correct half. Nobody scans a dictionary front to back.

The one hard requirement: the data must be sorted, or have some equivalent monotonic property (a "yes/no" answer that flips exactly once as you scan across the range) — binary search has no way to know which half to discard on unsorted data, because there's no guarantee about what's on either side of the midpoint.


Finding the First or Last Occurrence

Plain binary search finds a match, but stops as soon as it finds one — if the target appears multiple times, which one you get back is unspecified. Finding the first occurrence specifically requires a small but important tweak: don't stop on a match, keep searching left for an earlier one.

typescript

The last occurrence is the mirror image — record the match, then search right instead of left. Both variants stay O(log n); the only change is what you do on a match, not the halving logic itself.


Searching a Rotated Sorted Array

A sorted array that's been rotated (e.g. [4, 5, 6, 7, 0, 1, 2] — sorted, then rotated at index 4) isn't fully sorted anymore, but it has a useful property: at least one half of any split is still sorted, and you can tell which half by comparing the endpoints.

typescript

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.