Koko loves to eat bananas. There are n
piles of bananas, the i
-th 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.
For example:
piles = [3,6,7,11], h = 8
The output should be 4
.piles = [30,11,23,4,20], h = 5
The output should be 30
piles = [30,11,23,4,20], h = 6
The output should be 23
Can you devise an efficient algorithm to determine the minimum eating speed k
?
Here's how we can solve the Koko eating bananas problem efficiently.
A simple, but inefficient, way to solve this problem is to iterate through all possible values of k
(bananas per hour) starting from 1, and check if Koko can eat all the bananas within h
hours for each k
. The first k
that satisfies the condition is the minimum k
we are looking for.
Algorithm:
k = 1
.k
, calculate the total hours needed to eat all bananas.h
, return k
.k
and repeat steps 2 and 3.Code (Python):
def can_eat_all(piles, h, k):
hours = 0
for pile in piles:
hours += (pile + k - 1) // k # Ceil division
return hours <= h
def min_eating_speed_brute_force(piles, h):
k = 1
while True:
if can_eat_all(piles, h, k):
return k
k += 1
Big O Analysis:
We can use binary search to find the optimal value of k
. The minimum possible value of k
is 1, and the maximum possible value of k
is the largest pile size. We can perform a binary search within this range to find the minimum k
that satisfies the condition.
Algorithm:
left = 1
and right = max(piles)
.left < right
:
mid = left + (right - left) // 2
(to prevent overflow).mid
.h
, it means mid
might be a valid answer, so we try to reduce k
further by setting right = mid
.h
, it means mid
is too small, so we increase k
by setting left = mid + 1
.left
(or right
, since left == right
at the end).Code (Python):
def can_eat_all(piles, h, k):
hours = 0
for pile in piles:
hours += (pile + k - 1) // k # Ceil division
return hours <= h
def min_eating_speed(piles, h):
left, right = 1, max(piles)
while left < right:
mid = left + (right - left) // 2
if can_eat_all(piles, h, mid):
right = mid
else:
left = mid + 1
return left
Big O Analysis:
piles
. This is because we perform a binary search between 1 and the maximum pile size, and for each mid
value, we iterate through all the piles to calculate the total hours.piles
is empty: The problem statement says 1 <= piles.length <= 10^4
, so this case is not possible.h
is very small (close to the number of piles): This forces k
to be large. The binary search handles this case efficiently.h
is very large: This allows k
to be small. The binary search also handles this case without issues.hours
value could become large, but since we are only comparing it with h
(which is at most 10^9
), we do not need to worry about integer overflow issues assuming we are using a 64 bit integer.