Plain search tells you whether a value exists, but real indexes need to know where a value would go. lower_bound answers that: it returns the index of the first element that is greater than or equal to target. If every element is smaller, it returns len(arr), the position just past the end.
Implement lower_bound(arr, target):
This variant does not stop early on a match. That is deliberate: it always converges on the leftmost valid position, even with duplicates.
def search(arr, target):
lo, hi = 0, len(arr) - 1
while lo <= hi:
mid = (lo + hi) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
lo = mid + 1
else:
hi = mid - 1
return -1
def lower_bound(arr, target):
"""Return the index of the first element >= target, or len(arr)."""
# TODO: half-open search over [0, len(arr)]. Move lo past elements < target.
pass
The editor and the test runner need a wide screen. Open this page on a desktop browser and your progress will be waiting.
Plain search tells you whether a value exists, but real indexes need to know where a value would go. lower_bound answers that: it returns the index of the first element that is greater than or equal to target. If every element is smaller, it returns len(arr), the position just past the end.
Implement lower_bound(arr, target):
This variant does not stop early on a match. That is deliberate: it always converges on the leftmost valid position, even with duplicates.
Press Run Tests or ββ© to check your solution.