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 and a value , binary search finds the first index with (or reports if there is none) by repeatedly discarding half of the remaining candidates.
The invariant
Keep a half-open window and hold on to two facts:
- every index before has ;
- every index from onward has .
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, , so the two facts meet: everything before is and everything from on is . That is the answer.
Why it is fast
Each step shrinks by at least half, so the loop runs times instead of .
Common traps
- Overflow. Write
lo + (hi - lo) / 2instead of(lo + hi) / 2. - Infinite loops.
lo = mid(without the+ 1) can stall whenhi = lo + 1. Whenevermidis ruled out, move the boundary past it. - Mixing conventions. Pick half-open or closed and stay with it, because the loop condition and both updates change together.