Taro Logo

Koko Eating Bananas

Medium
Meta logo
Meta
Topics:
ArraysBinary Search

Koko loves to eat bananas. There are n piles of bananas, the i<sup>th</sup> 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.

Example 1:

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

Output: 4

Example 2:

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

Output: 30

Example 3:

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

Output: 23

Given an array of banana piles and a number h representing the hours the guards are away, determine the minimum eating speed k that will allow Koko to eat all the bananas before the guards return.

Solution


Koko Eating Bananas Solution

Here's how to solve the "Koko Eating Bananas" problem efficiently.

1. Naive (Brute Force) Solution

The simplest approach is to iterate through all possible values of k (bananas per hour), starting from 1, and for each k, calculate the total time Koko needs to eat all bananas. If the total time is less than or equal to h, then we've found a valid k. We keep track of the minimum k found so far. This continues until we find the solution.

Code (Python):

def time_to_eat(piles, k):
    time = 0
    for pile in piles:
        time += (pile + k - 1) // k  # Ceil division
    return time

def minEatingSpeed_brute_force(piles, h):
    k = 1
    while True:
        if time_to_eat(piles, k) <= h:
            return k
        k += 1

Time Complexity: O(max(piles) * n), where n is the number of piles. Space Complexity: O(1)

This brute force method is inefficient and will likely result in TLE (Time Limit Exceeded) for larger inputs.

2. Optimal Solution (Binary Search)

We can use binary search to find the minimum k. The range of possible values for k is between 1 and max(piles). We perform binary search within this range.

For a given k, we calculate the total time needed to eat all bananas. If the time is less than or equal to h, it means k might be a possible solution, and we try to reduce k further (move to the left half). Otherwise, k is too small, and we need to increase it (move to the right half).

Algorithm:

  1. Initialize left to 1 and right to max(piles).
  2. While left <= right:
    • Calculate mid = left + (right - left) // 2 (to prevent overflow).
    • Calculate time = sum((pile + mid - 1) // mid for pile in piles).
    • If time <= h, update right = mid - 1. Also, store the current mid as the potential minimum k.
    • Else, update left = mid + 1.
  3. Return the minimum k found.

Code (Python):

def minEatingSpeed(piles, h):
    left, right = 1, max(piles)
    ans = right # Initialize with the maximum possible value of k

    while left <= right:
        mid = left + (right - left) // 2
        time = sum((pile + mid - 1) // mid for pile in piles)

        if time <= h:
            ans = mid
            right = mid - 1
        else:
            left = mid + 1

    return ans

Time Complexity: O(n * log(max(piles))), where n is the number of piles. Space Complexity: O(1)

3. Edge Cases

  • Empty piles array: The problem states 1 <= piles.length <= 10^4, so we don't need to handle this explicitly.
  • h is very small: If h is equal to the number of piles, Koko must eat each pile in one hour. Thus, k would be the maximum value in the piles array.
  • h is very large: If h is sufficiently large, Koko can eat one banana per hour, so the lower bound of the search will be 1. This case is automatically handled by the binary search.

4. Explanation of Big O

  • Time Complexity: O(n * log(max(piles)))
    • The binary search takes O(log(max(piles))) iterations because we're searching within the range of 1 to max(piles).
    • In each iteration, we calculate the time needed to eat all piles, which takes O(n) time, where n is the number of piles.
    • Therefore, the overall time complexity is O(n * log(max(piles))).
  • Space Complexity: O(1)
    • We use only a constant amount of extra space for variables like left, right, mid, and time. The space used does not depend on the input size.