DAY 12 / 30 · WEEK 2

Binary Search

Goal of the day

Concept

Guess a number between 1 and 100. Instead of guessing 1, 2, 3, 4… (linear, up to 100 guesses), guess 50 first. Told "higher"? You just eliminated half the numbers in one guess. Guess the midpoint of what's left, every time — each guess halves the remaining possibilities, so 100 numbers takes at most 7 guesses, not 100. That halving is where O(log n) comes from: it's the number of times you can cut n in half before you're left with one candidate.

The catch: this only works if the search space is sorted (or more precisely, monotonic — see the Interview Corner for what that really means). On an unsorted array, "higher" or "lower" tells you nothing about where to look next.

Diagram: narrowing lo / mid / hi

Search for 9 in [1, 3, 5, 7, 9, 11, 13] 1 3 5 7 9 11 13 lo=0 mid=3 hi=6 arr[mid] = 7, target = 9 → 7 < 9, so the answer (if it exists) must be to the right. Eliminate index 0-3 (indices ≤ mid) entirely. Next round: lo=4, hi=6 — only [9, 11, 13] is still in play. One more comparison finds mid=4 → arr[4]=9 = target. Found in 3 steps, not 5 — that's the halving in action.

Interactive visualization: full binary search

current range [lo, hi] mid (checking now) eliminated found
Press Play or Step to begin.

The code

function search(nums, target) {
  let lo = 0, hi = nums.length - 1;
  while (lo <= hi) {                             // "="  matters — see below
    const mid = lo + Math.floor((hi - lo) / 2);   // not (lo+hi)/2 — see below
    if (nums[mid] === target) return mid;
    else if (nums[mid] < target) lo = mid + 1;    // answer is to the right
    else hi = mid - 1;                            // answer is to the left
  }
  return -1; // not found
}

Line by line:

Dry run: search([1, 3, 5, 7, 9, 11, 13], target=9)

lohimidarr[mid]Compare to 9Action
06377 < 9lo = 4 (search right half)
4651111 > 9hi = 4 (search left half)
44499 === 9return 4 — found

3 comparisons to search 7 elements — log₂(7) ≈ 2.8, rounded up to 3. Compare to a linear scan, which could take up to 7.

Diagram: the off-by-one trap that infinite-loops

Trap: lo = mid (instead of lo = mid + 1) can freeze forever State: lo=3, hi=4. mid = Math.floor((3+4)/2) = 3 — mid rounds down to equal lo. ✓ lo = mid + 1 → lo becomes 4, hi stays 4 ✗ lo = mid → lo stays 3, unchanged Next round: lo=4, hi=4 → loop condition lo < hi is false → exits cleanly. Next round: lo=3, hi=4 → identical state to before → mid=3 again → lo=3 again forever. The loop condition never becomes false. 🔁 infinite loop. This exact shape shows up in "search on answer" templates like today's Find Peak Element.

Complexity

ApproachTimeSpaceWhy
IterativeO(log n)O(1)Halves the search range each step — log₂n steps to reach 1 element. No extra memory beyond a few index variables.
RecursiveO(log n)O(log n)Same halving, but each recursive call adds a call-stack frame (Day 9) — log n frames deep before returning.

Interview corner

How to talk through it out loud: state the invariant first — "at every point in the loop, if the target exists, it's somewhere in [lo, hi]" — then justify each boundary update by showing it preserves that invariant. Naming the invariant explicitly is what separates "I memorized this template" from "I understand why this template is correct," and it's exactly what lets you adapt the template when a problem needs a different shape (like Day 13's variants).

Practice problems

1. Binary Search (Easy — LeetCode: Binary Search)

Given a sorted array of integers and a target value, return its index, or -1 if it's not present. This is today's template, applied directly.

2. Search in Rotated Sorted Array (Medium — LeetCode: Search in Rotated Sorted Array)

A sorted array has been rotated at an unknown pivot (e.g. [4,5,6,7,0,1,2]). Find a target's index in O(log n) time.

3. Find Peak Element (Medium — LeetCode: Find Peak Element)

Given an array where nums[-1] = nums[n] = -∞, find any index whose value is strictly greater than both neighbors. The array is not sorted — this is the clearest example of "binary search works on any monotonic yes/no question," not just literal sorted arrays.

Quiz

1. Why does using while (lo < hi) break the exact-match binary search template from today?

2. What is binary search's time complexity, and why?

3. What's the real requirement for binary search to work on a dataset?

4. What's the space-complexity difference between recursive and iterative binary search?

5. In a "search on answer" template using while (lo < hi), what bug does writing lo = mid instead of lo = mid + 1 risk?