Lesson 11 / 26
Binary Search on the Answer
When the answer space is monotonic.
Search over possible answers
If you can check "is answer x feasible?" and feasibility is monotonic (if capacity 15 works, 16 works too), binary search the answer range instead of the input. Typical problems: minimum ship capacity, minimum eating speed, smallest maximum subarray sum when splitting. Complexity is O(n log range), where each check is a greedy O(n) pass.
Minimum ship capacity, run
I ran this with Python 3.12.3 (standard library only). The search starts between the heaviest package and the total weight and finds capacities 15, 6 and 3 for the three test cases.
# Binary search on the answer: minimum ship capacity to deliver in D days
def days_needed(weights, cap):
days, load = 1, 0
for w in weights:
if load + w > cap:
days, load = days + 1, 0
load += w
return days
def ship_within_days(weights, D):
lo, hi = max(weights), sum(weights) # answer lies in this range
while lo < hi:
mid = (lo + hi) // 2
if days_needed(weights, mid) <= D:
hi = mid # feasible: try smaller
else:
lo = mid + 1
return lo
print(ship_within_days([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 5))
print(ship_within_days([3, 2, 2, 4, 1, 4], 3))
print(ship_within_days([1, 2, 3, 1, 1], 4))
Output:
15 6 3
Set the bounds carefully
The lower bound must be feasible-or-not and the upper bound must be feasible; here max(weights) and sum(weights).
Quick check: What property makes binary search on the answer valid?
- The array has no duplicates
- The input is sorted
- The answer is always an even number
- Feasibility is monotonic in the answer
Answer
Feasibility is monotonic in the answer — Once feasible, always feasible above.