Home
DSA Patterns
Binary Search
Apple Harvest (Koko Variant)
Apple Harvest (Koko Variant)
Find the minimum eating speed to finish all piles within H hours.
Problem Understanding
You have n piles of apples. The i-th pile has piles[i] apples.
You have H hours to eat all apples.
You can decide your eating speed k (apples per hour).
- Each hour, you choose a pile and eat up to
kapples from it. - If the pile has less than
kapples, you eat them all and stop for that hour (you don't move to the next pile).
Return the minimum integer k such that you can eat all apples within H hours.
Example
- Piles:
[3, 6, 7, 11], H:8 - If k=1: Needs 3+6+7+11 = 27 hours (> 8). Too slow.
- If k=4: Needs 1+2+2+3 = 8 hours (<= 8). Valid.
- Can we do better? Minimum k is our goal.
Attempt 1: Brute Force (Linear Search on k)
The possible speeds range from k=1 (slowest) to k=max(piles) (fastest - one pile per hour).
We can check every k starting from 1.
- Try k=1. Calculate hours. If <= H, return 1.
- Try k=2. Calculate hours. If <= H, return 2.
- ...
Time Complexity
O(max(P) * n). If max pile is 10^9, this is TLE (Time Limit Exceeded).
The Intuition: Binary Search on Answer
The valid speeds form a monotonic range:
- If speed
kis valid (we finish in time), then any speed> kis also valid (we finish even faster). - If speed
kis invalid (too slow), then any speed< kis also invalid.
This monotonicity allows us to use Binary Search on the search space of k (from 1 to max(piles)).
- Range: [1, max(piles)]
- Mid: Test if speed
midis feasible.- If feasible (
hours <= H): Thismidcould be the minimum, but maybe there's a smaller one? Storemidas answer, and search left (high = mid - 1). - If not feasible (
hours > H): Too slow! Need faster speed. Search right (low = mid + 1).
- If feasible (
Interactive Visualization
Step through the search on k and watch each speed’s total hours compared against H.
Dry Run
Piles: [3, 6, 7, 11], H = 8.
Range of k: [1, 11]
| Step | Low | High | Mid (k) | Hours Calculation | Total Hours | Condition (<= 8) | Action |
|---|---|---|---|---|---|---|---|
| 1 | 1 | 11 | 6 | ceil(3/6)+ceil(6/6)+ceil(7/6)+ceil(11/6) = 1+1+2+2 | 6 | 6 <= 8 (True) | Valid. Ans=6. Try slower. High=5 |
| 2 | 1 | 5 | 3 | ceil(3/3)+ceil(6/3)+ceil(7/3)+ceil(11/3) = 1+2+3+4 | 10 | 10 <= 8 (False) | Too slow. Try faster. Low=4 |
| 3 | 4 | 5 | 4 | ceil(3/4)+ceil(6/4)+ceil(7/4)+ceil(11/4) = 1+2+2+3 | 8 | 8 <= 8 (True) | Valid. Ans=4. Try slower. High=3 |
| 4 | 4 | 3 | - | Loop Ends | - | - | Return Ans=4 |
The Solution Template
Binary Search applied to answer range.
Apple Harvest (Koko Variant) Code
1/**2 * @param {number[]} piles3 * @param {number} h4 * @return {number}5 */6var minEatingSpeed = function(piles, h) {7 let low = 1;8 let high = Math.max(...piles);9 let ans = high;1011 while (low <= high) {12 let mid = Math.floor(low + (high - low) / 2);13 let hours = 0;14 for (let p of piles) {15 hours += Math.ceil(p / mid);16 }1718 if (hours <= h) {19 ans = mid;20 high = mid - 1;21 } else {22 low = mid + 1;23 }24 }25 return ans;26};
Edge Cases
- n == h: Must eat each pile in 1 hour. k = max(piles).
- Small piles: k could be small.
- Large piles: k logic handles up to max value.
- Integer Overflow: In Java/C++, sum of hours could exceed 2^31, use
long.
Summary
This is a classic 'Binary Search on Answer' problem. We search for the optimal parameter 'k' by validating candidates against the constraint 'target hours'.
