You are given an integer array piles where piles[i] is the number of bananas in the ith pile. You are also given an integer h, which represents the number of hours you have to eat all the bananas.
You may decide your bananas-per-hour eating rate of k. Each hour, you may choose a pile of bananas and eats k bananas from that pile. If the pile has less than k bananas, you may finish eating the pile but you can not eat from another pile in the same hour.
Return the minimum integer k such that you can eat all the bananas within h hours.
Example 1:
Input: piles = [1,4,3,2], h = 9
Output: 2Explanation: With an eating rate of 2, you can eat the bananas in 6 hours. With an eating rate of 1, you would need 10 hours to eat all the bananas (which exceeds h=9), thus the minimum eating rate is 2.
Example 2:
Input: piles = [25,10,23,4], h = 4
Output: 25Constraints:
1 <= piles.length <= 1,000piles.length <= h <= 1,000,0001 <= piles[i] <= 1,000,000,000
You should aim for a solution with O(nlogm) time and O(1) space, where n is the size of the input array, and m is the maximum value in the array.
Given h is always greater than or equal to the length of piles, can you determine the upper bound for the answer? How much time does it take Koko to eat a pile with x bananas?
It takes ceil(x / k) time to finish the x pile when Koko eats at a rate of k bananas per hour. Our task is to determine the minimum possible value of k. However, we must also ensure that at this rate, k, Koko can finish eating all the piles within the given h hours. Can you now think of the upper bound for k?
The upper bound for k is the maximum size of all the piles. Why? Because if Koko eats the largest pile in one hour, then it is straightforward that she can eat any other pile in an hour only.
Consider m to be the largest pile and n to be the number of piles. A brute force solution would be to linearly check all values from 1 to m and find the minimum possible value at which Koko can complete the task. This approach would take O(n * m) time. Can you think of a more efficient method? Perhaps an efficient searching algorithm could help.
Rather than linearly scanning, we can use binary search. The upper bound of k is max(piles) and since we are only dealing with positive values, the lower bound is 1. The search space of our binary search is 1 through max(piles). This allows us to find the smallest possible k using binary search.
Before attempting this problem, you should be comfortable with:
We try every possible eating speed starting from 1.
For each speed, we simulate how many hours it would take to finish all piles.
The first speed that finishes within h hours is the answer.
speed = 1.ceil(pile / speed) for every pile.h, return the current speed.Where is the length of the input array and is the maximum number of bananas in a pile.
Instead of checking every speed one by one, we notice that the total time needed decreases as the eating speed increases.
This means the answer lies in a sorted search space from 1 to max(piles).
Because the search space is ordered, we can use binary search to efficiently find the smallest speed that allows finishing the piles within h hours.
left = 1 (minimum possible speed)right = max(piles) (maximum needed speed)left <= right:mid be the current speed to test.h:class Solution:
def minEatingSpeed(self, piles: List[int], h: int) -> int:
l, r = 1, max(piles)
res = r
while l <= r:
k = (l + r) // 2
totalTime = 0
for p in piles:
totalTime += math.ceil(float(p) / k)
if totalTime <= h:
res = k
r = k - 1
else:
l = k + 1
return resWhere is the length of the input array and is the maximum number of bananas in a pile.
When calculating hours needed per pile, you must round up since Koko spends a full hour even if fewer bananas remain. Using regular integer division gives wrong results.
# Wrong: Integer division rounds down
totalTime += pile // speed
# Correct: Ceiling division
totalTime += math.ceil(pile / speed)
# Or without import:
totalTime += (pile + speed - 1) // speedThe minimum speed is 1 (not 0, which would cause division by zero). The maximum speed needed is max(piles) since eating faster than the largest pile provides no benefit.
# Wrong: Starting from 0
l = 0 # Division by zero!
# Wrong: Arbitrary upper bound
r = sum(piles) # Unnecessarily large
# Correct bounds
l, r = 1, max(piles)When summing hours across all piles, the total can exceed 32-bit integer limits for large inputs. Use a long integer type in languages like Java/C++.
// Wrong: May overflow
int totalTime = 0;
// Correct: Use long
long totalTime = 0;