Binary Search on Answer Technique
Learn to binary search on the answer space — the powerful technique behind problems like splitting arrays, Koko eating bananas, and capacity to ship packages.
What you'll learn
- ✓When to binary search on the answer instead of the input
- ✓The feasibility-check pattern and how to write it
- ✓Solving Koko Eating Bananas, Ship Packages, and Split Array
- ✓How to define the search space boundaries
- ✓Common pitfalls with off-by-one in answer-space binary search
Prerequisites
- •Standard binary search on a sorted array
- •Basic greedy reasoning
Standard binary search finds a target in a sorted array. Binary search on the answer is different — you binary search over the range of possible answers, and for each candidate answer you check whether it’s feasible. If the feasibility function is monotonic (all True then all False, or vice versa), binary search finds the boundary in O(log(range) × check).
The Pattern
Answer space: [lo … hi]
For each mid = (lo + hi) // 2:
if feasible(mid):
record mid as a candidate
search for a better answer (move hi or lo)
else:
search the other half
The template for minimizing the answer:
def binary_search_on_answer(lo, hi, feasible):
while lo < hi:
mid = (lo + hi) // 2
if feasible(mid):
hi = mid
else:
lo = mid + 1
return lo
For maximizing the answer, flip it:
def binary_search_on_answer_max(lo, hi, feasible):
while lo < hi:
mid = (lo + hi + 1) // 2
if feasible(mid):
lo = mid
else:
hi = mid - 1
return lo
Problem 1: Koko Eating Bananas (LeetCode 875)
Koko has n piles of bananas. She can eat at speed k bananas per hour (one pile per hour, even if it has fewer than k). Find the minimum k to finish all piles in h hours.
import math
def min_eating_speed(piles, h):
def feasible(k):
hours = sum(math.ceil(p / k) for p in piles)
return hours <= h
lo, hi = 1, max(piles)
while lo < hi:
mid = (lo + hi) // 2
if feasible(mid):
hi = mid
else:
lo = mid + 1
return lo
print(min_eating_speed([3, 6, 7, 11], 8)) # 4
Search space: lo = 1 (minimum speed), hi = max(piles) (eat any pile in one hour).
Feasibility: at speed k, total hours is Σ ceil(pile / k). If that’s ≤ h, the speed works.
Problem 2: Capacity to Ship Packages (LeetCode 1011)
Find the minimum ship capacity to ship all packages within days days, preserving order.
def ship_within_days(weights, days):
def feasible(capacity):
day_count = 1
current_load = 0
for w in weights:
if current_load + w > capacity:
day_count += 1
current_load = 0
current_load += w
return day_count <= days
lo = max(weights)
hi = sum(weights)
while lo < hi:
mid = (lo + hi) // 2
if feasible(mid):
hi = mid
else:
lo = mid + 1
return lo
print(ship_within_days([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 5)) # 15
Search space: lo = max(weights) (must carry the heaviest single package), hi = sum(weights) (ship everything in one day).
Problem 3: Split Array Largest Sum (LeetCode 410)
Split an array into k subarrays to minimize the largest subarray sum. This is the same structure — binary search on the maximum allowed sum.
def split_array(nums, k):
def feasible(max_sum):
splits = 1
current = 0
for n in nums:
if current + n > max_sum:
splits += 1
current = 0
current += n
return splits <= k
lo = max(nums)
hi = sum(nums)
while lo < hi:
mid = (lo + hi) // 2
if feasible(mid):
hi = mid
else:
lo = mid + 1
return lo
print(split_array([7, 2, 5, 10, 8], 2)) # 18
How to Spot These Problems
Look for these clues:
- “Minimize the maximum” or “maximize the minimum” — classic binary search on answer phrasing.
- The brute-force answer range is bounded and ordered.
- There’s a greedy way to check if a candidate answer works.
- The feasibility check is monotonic: if answer
xworks, thenx+1also works (for minimization).
Defining the Search Space
Getting lo and hi right is crucial:
| Problem Type | lo | hi |
|---|---|---|
| Minimum speed/capacity | 1 or max(single element) | max(all) or sum(all) |
| Minimum max-sum after split | max(element) | sum(all) |
| Maximum minimum distance | 0 | max_position - min_position |
Complexity Analysis
| Aspect | Value |
|---|---|
| Time | O(n × log(hi - lo)) |
| Space | O(1) extra |
The log factor is over the answer range, and the feasibility check is typically O(n).
Interview Tips
- State the search space bounds explicitly before coding — interviewers want to see you reason about
loandhi. - Always verify the feasibility function is monotonic: “if
kworks, doesk+1also work?” - Use
lo < hiwithhi = midfor minimize, andlo < hiwithlo = mid(plusmid = (lo + hi + 1) // 2) for maximize. This avoids infinite loops. - Common bug: setting
lotoo low. If capacity must be at leastmax(weights), starting at0wastes iterations and can break the check. - The greedy feasibility check is usually straightforward — practice writing it quickly.
Related articles
- DSA Binary Search on Answer: Advanced Problems
Solve advanced binary search on answer problems — Koko eating bananas, ship packages, split array largest sum, minimize max distance to gas station, and magnetic force between balls.
- DSA Binary Search Patterns: Templates, Rotated Arrays, and Answer Space
Master binary search with three templates -- exact match, first/last true, and answer space search. Covers rotated arrays, peak elements, and common off-by-one mistakes.
- DSA Longest Increasing Subsequence: DP and Patience
Longest Increasing Subsequence in detail — the O(n^2) DP, the O(n log n) patience-sorting trick with binary search, and when each one matters.
- DSA Search in Rotated Sorted Array: Modified Binary Search
Solve Search in Rotated Sorted Array in O(log n) with modified binary search. Pivot detection, half-decision logic, and interview talking points.