Problem Statement

Koko Eating Bananas

Koko loves bananas. There are several piles in front of her, and pile i has piles[i] bananas. The guards left and come back in h hours. Koko picks one eating speed k, which means k bananas per hour. Each hour she eats from a single pile: if that pile has fewer than k bananas left, she finishes it and waits out the rest of the hour (she does not start a new pile until the next hour). We want the smallest whole-number speed k that still lets her finish every banana before the guards return in h hours. A slower speed is nicer for Koko, so we want the smallest k that works.

mediumBinary SearchBinary SearchTime: O(n log m) · Space: O(1)

Signals to notice

minimize maximum eating speedcan finish in h hours?binary search on the answer

Brute force first

Try every speed from 1 to max(piles) and simulate. Tests every possible speed linearly. That direct path helps you understand the question, but it tends to treat every possibility as brand new instead of learning from earlier steps.

The key insight

Binary search on the speed: for each candidate speed, check if Koko can finish all piles in h hours. The check is, and binary search reduces candidates from max to log(max). Total. Instead of recomputing the world every time, you preserve just enough context to let the next decision become obvious.

Trace it on piles=[3,6,7,11], h=8

init: left=1, right=max(piles)=11
mid=6 -> hours=1+1+2+2=6 <=8 -> right=6 (6 might work, try slower)
mid=3 -> hours=1+2+3+4=10 >8 -> left=4 (too slow, need faster)
mid=5 -> hours=1+2+2+3=8 <=8 -> right=5
mid=4 -> hours=1+2+2+3=8 <=8 -> right=4
left==right==4 -> loop ends
return left = 4

What must stay true

If Koko can finish at speed k, she can finish at any speed > k. If she can't finish at speed k, she can't at any speed < k. This monotonicity makes binary search valid. As long as that statement keeps holding, you can trust the steps built on top of it.

Shape of the loop

left, right = 1, max(piles)
while left < right:
    mid = (left + right) // 2
    hours = sum(ceil(p / mid) for p in piles)
    if hours <= h: right = mid      # feasible, search slower speeds
    else:          left = mid + 1   # too slow, search faster speeds
return left

Pseudocode only — the full worked solution lives in the Solution tab.

Easy way to go wrong

The ceiling division: hours for one pile = ceil(pile / speed), not floor. Forgetting ceiling means underestimating the time. Most mistakes here are not about syntax; they come from losing track of what your state, pointer, or structure is supposed to mean.

Binary Search Pattern