Koko Eating Bananas
The drill: Find the slowest whole-bananas-per-hour eating speed that still clears every pile within h hours — each hour is spent on one pile only, and a pile finished early wastes the rest of that hour.
Koko faces a row of banana piles and a fixed number of hours before the guards return; she picks one eating speed, in whole bananas per hour, and sticks with it for the entire ordeal.
Each hour she commits to a single pile: if the pile has fewer bananas than her speed, she finishes it early and the leftover time in that hour is wasted rather than carried to the next pile.
The job is to find the smallest whole-number speed that still lets her clear every pile within the hour budget — slower is kinder to the bananas but risks running out of time.
- piles list holds up to a few thousand piles, each with a positive banana count
- hour budget is always at least as large as the number of piles
- eating speed must be a positive whole number, never zero or fractional
- an hour spent on a nearly empty pile still costs the full hour
HINT 1 THE NUDGE
Faster speeds always finish in fewer or equal hours than slower ones — hours-to-finish is monotonic in speed, which is exactly what makes bisecting the speed itself work.
HINT 2 THE STRUCTURE
For a candidate speed, the hours needed is the sum of ceil(pile / speed) over every pile — compute that directly instead of simulating hour by hour.
HINT 3 ONE STEP FROM THE ANSWER
Binary-search speed in [1, max(piles)]: if the hours needed at mid exceeds h, mid is too slow — raise it; otherwise it's fast enough — try to go slower.
4 piles: 3, 6, 7, 11 bananas. Binary-search Koko's speed in [1, 11] — the biggest pile — for the slowest speed that clears them in 8 hours.
class Solution:
def minEatingSpeed(self, piles: List[int], h: int) -> int:
lo, hi = 1, max(piles)
while lo < hi:
mid = (lo + hi) // 2
hours = sum((p + mid - 1) // mid for p in piles)
if hours <= h:
hi = mid
else:
lo = mid + 1
return loclass Solution:
def minEatingSpeed(self, piles: List[int], h: int) -> int:
speed = 1
while True:
hours = sum((p + speed - 1) // speed for p in piles)
if hours <= h:
return speed
speed += 1class Solution {
public int minEatingSpeed(int[] piles, int h) {
int lo = 1, hi = 0;
for (int p : piles) {
hi = Math.max(hi, p);
}
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
long hours = 0;
for (int p : piles) {
hours += (p + mid - 1) / mid;
}
if (hours <= h) {
hi = mid;
} else {
lo = mid + 1;
}
}
return lo;
}
}class Solution {
public int minEatingSpeed(int[] piles, int h) {
int speed = 1;
while (true) {
long hours = 0;
for (int p : piles) {
hours += (p + speed - 1) / speed;
}
if (hours <= h) {
return speed;
}
speed++;
}
}
}✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED