Koko Eating Bananas

Binary search the answer: eating speed is monotonic in whether she finishes in time.

Search Over Speeds

The answer is a speed from left = 1 to right = 11, the biggest pile.
StopBinary searchExport
pilesh

speed

piles36711
  • CH1 left
  • CH2 right

Problem

Koko has several banana piles and can eat from only one pile during each hour. At a speed of k bananas per hour, she spends ceil(pile / k) hours on each pile. Return the smallest integer speed that allows her to finish all piles within h hours.

Examples

Input: piles = [3,6,7,11], h = 8

Output: 4

At speed 4, the required hours are 1 + 2 + 2 + 3 = 8. Any slower speed takes more than 8 hours.

Input: piles = [30,11,23,4,20], h = 5

Output: 30

There are five piles and only five hours, so Koko must finish one pile per hour. The largest pile requires speed 30.

The Goal

Each hour, Koko eats up to k bananas from one pile. A smaller pile is finished early, and she waits out the hour. Find the smallest k that finishes every pile within h hours.

For piles = [3, 6, 7, 11] and h = 8, the answer is 4. At speed 4 the piles take 1 + 2 + 2 + 3 = 8 hours.

A pile of p takes p / k hours, rounded up.

Fast enough or not?

For any speed, add up each pile's hours, rounded up. Either the total fits in h or it doesn't.

Search for the slowest speed that fits.

Key Idea: Search the Speeds, Not the Piles

A faster speed never takes more hours. So the speeds from 1 to the biggest pile line up as too slow, then fast enough from some speed on.

That makes them searchable. Try the middle speed. If it's fast enough, the answer is it or slower. If not, the answer is faster.

The piles don't need to be sorted. The speeds are what's in order.

If a speed works, every faster speed works too.

3 takes 10 hours; 4 takes 8

The Algorithm

Start with left = 1 and right = max(piles). The biggest pile's speed finishes each pile in an hour, so it always works when h is at least the number of piles.

python
while left < right:
    mid = (left + right) // 2
    hours = sum((p + mid - 1) // mid for p in piles)
    if hours <= h:
        right = mid
    else:
        left = mid + 1
return left

(p + mid - 1) // mid is p / mid rounded up, in whole numbers.

Walkthrough

Run it on piles = [3, 6, 7, 11] with h = 8.

Speeds 1 to 11 are in play. Speed 6 takes 6 hours, so right = 6. Speed 3 takes 10, too slow, so left = 4. Speed 5 takes 8, so right = 5. Speed 4 also takes 8, so right = 4. Now left = right = 4.

The answer, 4, isn't a pile size. It can be any speed.

Checkpoint · predict the next step

Step 5 of 14 on the stage: Try the middle speed: mid = 3 bananas an hour.

left = 1 · right = 6 · mid = 3 · h 8

What does step 6 show?
Step through it on the stage

Pitfalls

  • Round up. p // k undercounts any pile that doesn't divide evenly.
  • Start left at 1. Speed 0 never finishes.
  • Keep mid when it works: right = mid, not mid - 1.
  • When h equals the number of piles, each pile gets one hour, so the answer is the biggest pile.
  • In languages with fixed-size integers, the hour total can overflow. Use a wide type.

For piles = [3, 6, 7, 11] and h = 8, what does the binary search run over?

Complexity

Each try adds up all n piles: O(n). The speed range halves each try, so there are O(log m) tries, where m is the biggest pile.

That's O(n log m) time and O(1) extra space.

A binary search over speeds

Time
O(n log m)
Space
O(1)
Where the time goes
  • One tryAdd up every pile's hours.O(n)
  • Number of triesm is the biggest pile.O(log m)
  • Stateleft, right, mid and the total.O(1)
How it grows
input size n →opsO(n²)O(n log n)O(n)O(log n)O(1)

A few tries, each one pass over the piles.

In short

The feasible speeds form a monotonic predicate — any speed fast enough works, slower ones don't. Binary search speeds between 1 and max(pile); for each candidate, sum the hours needed and check against h. Return the smallest feasible speed.

TimeO(n log max)SpaceO(1)

Common mistake

Searching values in the array instead of the answer space [1, max pile] — this is 'binary search on the answer'.