Lewati ke konten utama
← Materi

Binary search

Halve the search space every step: the invariant that makes it correct, and the off-by-one traps.

What it does

Given a sorted array a0≤a1≤⋯≤an−1a_0 \le a_1 \le \dots \le a_{n-1} and a value xx, binary search finds the first index ii with ai≥xa_i \ge x (or reports nn if there is none) by repeatedly discarding half of the remaining candidates.

The invariant

Keep a half-open window [lo,hi)[lo, hi) and hold on to two facts:

  • every index before lolo has ai<xa_i < x;
  • every index from hihi onward has ai≥xa_i \ge x.
lo = 0
hi = n
while lo < hi:
    mid = lo + (hi - lo) / 2
    if a[mid] < x:
        lo = mid + 1      # a[0..mid] are all < x
    else:
        hi = mid          # a[mid..] are all >= x
return lo                 # first index with a[i] >= x

When the loop ends, lo=hilo = hi, so the two facts meet: everything before lolo is <x< x and everything from lolo on is ≥x\ge x. That is the answer.

Why it is fast

Each step shrinks hi−lohi - lo by at least half, so the loop runs O(log⁡n)O(\log n) times instead of O(n)O(n).

Common traps

  • Overflow. Write lo + (hi - lo) / 2 instead of (lo + hi) / 2.
  • Infinite loops. lo = mid (without the + 1) can stall when hi = lo + 1. Whenever mid is ruled out, move the boundary past it.
  • Mixing conventions. Pick half-open [lo,hi)[lo, hi) or closed [lo,hi][lo, hi] and stay with it, because the loop condition and both updates change together.

Editorial terkait