Binary search: find a boundary
Picture
In [no,no,no,yes,yes], the answer is the first yes, not merely any yes.
Predict
If middle is true, may we discard middle too?
Walk through the small example
No. Answers change once from false to true, so one comparison discards half while preserving the boundary.
Mental model and complete Python solution
Imagine a row of false answers followed by true answers. The algorithm is not searching for a value; it is squeezing the single border between those regions.
What the function promises: Return the first index whose value is at least target, or len(values). Input must be nondecreasing.
def lower_bound(values, target):
left, right = 0, len(values)
while left < right:
middle = (left + right) // 2
if values[middle] >= target:
right = middle
else:
left = middle + 1
return left
assert lower_bound([1,2,2,4], 2) == 1
assert lower_bound([1,2,2,4], 3) == 3
assert lower_bound([], 3) == 0
Work and storage: O(log n) time and O(1) space.
When to recognize it: Answers change once from false to true, so one comparison discards half while preserving the boundary.
Check before applying it: Off-by-one errors come from mixing interval conventions or searching a predicate that flips more than once.
Change one rule
The predicate is true, then false, then true again.
See what changes
Ordinary boundary binary search is invalid; find another monotone quantity or inspect the separate regions.
Connect
invariants: State exactly which interval still contains the boundary.
binary search answer: The same boundary search can operate on answer values.