Eliminate half the search space every step. O(log n) — at n=1,000,000, only 20 steps needed.
| n | Max Steps |
|---|---|
| 16 | 4 |
| 1,000 | 10 |
| 1,000,000 | 20 |
| 1,000,000,000 | 30 |
left <= right for classic search (single-element arrays must be checked). Use left < right for answer-space binary search.Piles: [3, 6, 7, 11]. Hours limit h=8. Find minimum eating speed k.
def binary_search(arr, target): left, right = 0, len(arr) - 1 while left <= right: # <= checks single element mid = left + (right - left) // 2 # avoids overflow if arr[mid] == target: return mid elif arr[mid] < target: left = mid + 1 else: right = mid - 1 return -1 # not found # Search Insert Position — return left at end def search_insert(arr, target): left, right = 0, len(arr) - 1 while left <= right: mid = (left + right) // 2 if arr[mid] == target: return mid elif arr[mid] < target: left = mid + 1 else: right = mid - 1 return left # insert position
def min_feasible_answer(arr, limit): def feasible(mid): # return True if mid satisfies the condition return sum(-(-x // mid) for x in arr) <= limit left, right = 1, max(arr) while left < right: # < not <= for answer search mid = (left + right) // 2 if feasible(mid): right = mid # mid works, try smaller else: left = mid + 1 # mid doesn't work, need bigger return left
left <= right. Answer-space: left < right. When feasible(mid) is True, right = mid (not mid-1) to preserve the answer.