Problem

Koko loves bananas 🍌.

You’re given an array piles where each element represents the number of bananas in a pile. Koko has exactly h hours to finish all the bananas.

She chooses an eating speed k (bananas per hour). During each hour:

  • She picks one pile.
  • Eats up to k bananas from that pile.
  • If the pile has fewer than k bananas, she finishes that pile.
  • She cannot move to another pile in the same hour.

Your task is to find the minimum integer eating speed k that allows Koko to finish all the bananas within h hours.


Example

Example 1

Input:
piles = [1,4,3,2]
h = 9

Output:
2

At a speed of 2 bananas/hour:

Pile

Hours Needed

1

1

4

2

3

2

2

1

Total = 6 hours, which is within 9 hours.

If Koko eats only 1 banana/hour, she would need:

1 + 4 + 3 + 2 = 10 hours

which exceeds the limit.


First Observation

We are asked to find the minimum possible speed.

This immediately hints at Binary Search.

However, we’re not searching inside the array.

Instead, we’re searching over the range of possible answers.


What is the Search Space?

The eating speed can never be:

  • Less than 1
  • Greater than the largest pile

So our search space is:

left = 1
right = max(piles)

For example,

piles = [25,10,23,4]

Possible speeds are:

1 2 3 4 ... 25

We’re looking for the smallest speed that works.


Why Binary Search Works

Suppose a speed of 6 bananas/hour allows Koko to finish on time.

Then:

  • 7 bananas/hour also works
  • 8 works
  • 20 works

Once a speed works, every larger speed also works.

Likewise,

If speed 5 is too slow,

then

  • 4 won’t work
  • 3 won’t work
  • 2 won’t work

This creates a monotonic search space, making binary search the perfect solution.

Too Slow        Works
XXXXXXXXXXXXYYYYYYYYYYY
            ^
      First valid answer

How Many Hours Does a Speed Take?

Suppose

speed = 4
pile = 10

Koko eats:

Hour 1 -> 4 bananas
Hour 2 -> 4 bananas
Hour 3 -> 2 bananas

Total:

3 hours

This is simply:

ceil(10 / 4)

For every pile,

hours += ceil(pile / speed)

Binary Search Process

Choose the middle speed:

mid = (left + right) // 2

Compute the total hours needed.

If

totalHours <= h

The speed works.

But maybe we can eat even slower, so we search the left half.

answer = mid
right = mid - 1

Otherwise

The speed is too slow.

We must increase it.

left = mid + 1

Dry Run

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

Search space:

1 ... 11

Mid = 6

Hours:

ceil(3/6)=1
ceil(6/6)=1
ceil(7/6)=2
ceil(11/6)=2

Total = 6

6 ≤ 8

Works.

Try smaller.


Mid = 3

Hours:

1 + 2 + 3 + 4 = 10

Too many hours.

Need a larger speed.


Continue until the smallest valid speed is found.


Python Solution

from typing import List
import math

class Solution:
    def minEatingSpeed(self, piles: List[int], h: int) -> int:
        l, r = 1, max(piles)
        res = r

        while l <= r:
            mid = l + (r - l) // 2
            totalTime = 0

            for pile in piles:
                totalTime += math.ceil(pile / mid)

            if totalTime <= h:
                res = mid
                r = mid - 1
            else:
                l = mid + 1

        return res

Complexity Analysis

Let:

  • n = number of piles
  • m = maximum pile size

For every binary search step, we scan all piles once.

  • Binary Search: O(log m)
  • Checking one speed: O(n)

Overall complexity:

Time:  O(n log m)
Space: O(1)

Key Takeaways

This problem is a classic example of Binary Search on the Answer.

The biggest clue isn’t that the array is sorted—it isn’t. The real insight is that the set of possible answers is ordered. Once a particular eating speed is fast enough, every higher speed will also work. That monotonic property allows us to efficiently search the answer space instead of testing every possible speed.

Whenever you encounter a problem asking for the minimum or maximum value that satisfies a condition, consider whether the answer space is monotonic. If it is, binary search on the answer is often the optimal approach.