Koko loves to eat bananas. There are n piles of bananas, the ith pile has piles[i] bananas. The guards have gone and will come back in h hours.
Koko can decide her bananas-per-hour eating speed of k. Each hour, she chooses some pile of bananas and eats k bananas from that pile. If the pile has less than k bananas, she eats all of them instead and will not eat any more bananas during this hour.
Koko likes to eat slowly but still wants to finish eating all the bananas before the guards return.
Return the minimum integer k such that she can eat all the bananas within h hours.
Input: piles = [3,6,7,11], h = 8
Output: 4
Explanation: At speed k=4, Koko eats: ceil(3/4)=1h, ceil(6/4)=2h, ceil(7/4)=2h, ceil(11/4)=3h = 8h total
Input: piles = [30,11,23,4,20], h = 5
Output: 30
Explanation: With only 5 hours and 5 piles, Koko must eat 1 pile per hour. Max pile is 30, so k=30.
Input: piles = [30,11,23,4,20], h = 6
Output: 23
Explanation: At k=23, she finishes in exactly 6 hours.
This is a binary search on the answer problem! The key insight:
Instead of testing every speed linearly O(max), use binary search O(log max).
This is Binary Search on Answer Space with these characteristics:
Define Search Space:
left = 1 (minimum eating speed)right = max(piles) (maximum eating speed)Binary Search on Speed:
mid = left + (right - left) / 2mid in h hoursCheck Feasibility:
hours += ceil(pile / k)Minimize k:
right = mid - 1 (try slower speed)left = mid + 1 (need faster speed)Return: left (minimum feasible speed)
Time Complexity: O(n * log(max)) where n = number of piles, max = largest pile
Space Complexity: O(1)
1class Solution {
2 public int minEatingSpeed(int[] piles, int h) {
3 // Binary search on eating speed
4 int left = 1;
5 int right = findMax(piles);
6
7 while (left < right) {
8 int mid = left + (right - left) / 2;
9
10 if (canFinish(piles, mid, h)) {
11 // mid works, try smaller speed
12 right = mid;
13 } else {
14 // mid too slow, need faster speed
15 left = mid + 1;
16 }
17 }
18
19 return left;
20 }
21
22 private boolean canFinish(int[] piles, int k, int h) {
23 int hours = 0;
24 for (int pile : piles) {
25 // Ceiling division: (pile + k - 1) / k
26 hours += (pile + k - 1) / k;
27 if (hours > h) return false; // Early termination
28 }
29 return hours <= h;
30 }
31
32 private int findMax(int[] piles) {
33 int max = 0;
34 for (int pile : piles) {
35 max = Math.max(max, pile);
36 }
37 return max;
38 }
39}
40