Sweaty Imposter

Koko Eating Bananas

MediumModified Binary SearchNeetCode 150MidOpen on LeetCodeUpdated

Koko has n piles of bananas, where piles[i] is the number in pile i, and h hours before the guards return. She picks one integer speed k, in bananas per hour. Each hour she eats k bananas from a single pile; if that pile has fewer than k left, she finishes it and waits out the rest of the hour without moving to another pile. Return the smallest k that lets her finish every pile within h hours. h is at least the number of piles, so an answer always exists.

Examples

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

At speed 4 the piles take 1 + 2 + 2 + 3 = 8 hours, which fits. At speed 3 they take 1 + 2 + 3 + 4 = 10 hours, which is too many.

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

With 5 piles and only 5 hours, every pile must be finished in a single hour, so k must be at least the largest pile, 30.

piles = [30,11,23,4,20], h = 6 returns 23

At speed 23 the piles take 2 + 1 + 1 + 1 + 1 = 6 hours. At speed 22 both the 30 and the 23 pile need 2 hours, for 7 in total.

Constraints

  • 1 <= piles.length <= 10^4
  • piles.length <= h <= 10^9
  • 1 <= piles[i] <= 10^9

Hints

Hint 1

The eating speed itself is bounded and monotonic, slower speeds risk running out of time and faster always work. What can you search?

Hint 2
A pointer toward the approach
Hint 3
The full approach, step by step

Drill This: Your Approach First

Approach

Hours needed only go down as the speed goes up, so search the speed range 1 to max(piles) for the first speed that fits. For a candidate mid, the hours are the sum of ceil(p / mid) over all piles, computed as (p + mid - 1) / mid in integer math. If that is at most h, mid works and something slower might too, so set hi = mid; otherwise set lo = mid + 1. O(n log m) time, where m = max(piles), and O(1) space.

Time

O(n log m)

Space

O(1)

Pitfall

Using p / k without rounding up, which counts a partial pile as zero hours. In Java, sum the hours in a long: 10^4 piles of 10^9 bananas at speed 1 overflow an int.

Solutions

class 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;
    }
}
Drill This