Open In App

Koko Eating Bananas

Last Updated : 13 Jun, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

You are given an array arr[] of n integers, where each element represents a pile of bananas. Koko has k hours to finish all the piles, and it's guaranteed that n ≤ k. Your task is to find the minimum number of bananas per hour, x, that Koko must eat to finish all the bananas within k hours.
Each hour, Koko can choose any pile and eat up to x bananas from it. If a pile has x or fewer bananas, she eats the whole pile in that hour.

Examples:

Input: arr[] = [5, 10, 3], k = 4
Output: 5
Explanation: If Koko eats at the rate of 5 bananas per hour:

  • First pile of 5 bananas will be finished in 1 hour.
  • Second pile of 10 bananas will be finished in 2 hours.
  • Third pile of 3 bananas will be finished in 1 hours.

Therefore, Koko can finish all piles of bananas in 1 + 2 + 1 = 4 hours.

Input: arr[] = [5, 10, 15, 20], k = 7
Output: 10
Explanation: If Koko eats at the rate of 10 bananas per hour, it will take 6 hours to finish all the piles.

[Naive Approach] Using Linear Search - O(n * m) time and O(1) space

The idea is to evaluate each possible speed, starting from 1, and calculate the total time needed for Koko to eat all the bananas at that speed. The minimum speed at which the total eating time is less than or equal to k hours is our answer. In this way, Koko eats all the bananas within the allowed time at the slowest possible pace.

C++
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// Function to find the minimum eating speed to finish bananas within k hours
int kokoEat(vector<int>& arr, int k) {
    int mx = *max_element(arr.begin(), arr.end());

    for (int speed = 1; speed <= mx; speed++) {
        long long time = 0;

        for (int i = 0; i < arr.size(); i++) {
            // Add the time needed to eat this pile at the current speed
            time += arr[i] / speed;
            if (arr[i] % speed != 0) {
                // Extra hour for remaining bananas
                time++;  
            }
        }

        // If total time is within allowed hours, return this speed
        if (time <= k) {
            return speed;
        }
    }
    
    // If no smaller speed works, return the max pile size
    return mx; 
}

// Driver code
int main() {
    vector<int> arr = {5, 10, 3};
    int k = 4;

    int minSpeed = kokoEat(arr, k);
    cout << minSpeed << endl;

    return 0;
}
Java
import java.util.Arrays;

class GfG {
    static int kokoEat(int[] arr, int k) {
        int mx = Arrays.stream(arr).max().getAsInt();
      
        for (int speed = 1; speed <= mx; speed++) {
            
            long time = 0;
            for (int i = 0; i < arr.length; i++) {
              
                // Time required to eat this pile 
                // of bananas at current speed
                time += arr[i] / speed;

                // 1 extra hour to eat the remainder 
                // number of bananas in this pile
                if (arr[i] % speed != 0) {
                    time++;
                }
            }
            
            // If total eating time at current speed
            // is smaller than given time
            if (time <= k) {
                return speed;
            }
        }
      
        return mx;
    }

    public static void main(String[] args) {
        int[] arr = {5, 10, 3};
        int k = 4;
        System.out.println(kokoEat(arr, k));
    }
}
Python
def kokoEat(arr, k):
    mx = max(arr)
  
    for speed in range(1, mx + 1):
      
        time = 0
        for i in range(len(arr)):
          
            # Time required to eat this pile 
            # of bananas at current speed
            time += arr[i] // speed

            # 1 extra hour to eat the remainder 
            # number of bananas in this pile
            if arr[i] % speed != 0:
                time += 1
        
        # If total eating time at current speed
        # is smaller than given time
        if time <= k:
            return speed
  
    return mx

if __name__ == "__main__":
    arr = [5, 10, 3]
    k = 4
    print(kokoEat(arr, k))
C#
using System;
using System.Linq;

class GfG {
    static int kokoEat(int[] arr, int k) {
        int mx = arr.Max();
      
        for (int speed = 1; speed <= mx; speed++) {
            
            long time = 0;
            for (int i = 0; i < arr.Length; i++) {
              
                // Time required to eat this pile 
                // of bananas at current speed
                time += arr[i] / speed;

                // 1 extra hour to eat the remainder 
                // number of bananas in this pile
                if (arr[i] % speed != 0) {
                    time++;
                }
            }
            
            // If total eating time at current speed
            // is smaller than given time
            if (time <= k) {
                return speed;
            }
        }
      
        return mx;
    }

    static void Main() {
        int[] arr = {5, 10, 3};
        int k = 4;
        Console.WriteLine(kokoEat(arr, k));
    }
}
JavaScript
function kokoEat(arr, k) {
    let mx = Math.max(...arr);
  
    for (let speed = 1; speed <= mx; speed++) {
      
        let time = 0;
        for (let i = 0; i < arr.length; i++) {
          
            // Time required to eat this pile 
            // of bananas at current speed
            time += Math.floor(arr[i] / speed);

            // 1 extra hour to eat the remainder 
            // number of bananas in this pile
            if (arr[i] % speed !== 0) {
                time++;
            }
        }
      
        // If total eating time at current speed
        // is smaller than given time
        if (time <= k) {
            return speed;
        }
    }
  
    return mx;
}

let arr = [5, 10, 3];
let k = 4;
console.log(kokoEat(arr, k));

Output
5

Time Complexity: O(n * m), where m is maximum bananas among all piles.
Auxiliary Space: O(1)

[Expected Approach] Using Binary Search - O(n * log m) time and O(1) space

The idea is to solve the problem by applying binary search on answer.

  • Lower limit of speed is 1 banana/hr as Koko must eat at least one banana per hour, and Upper limit is the maximum bananas among all piles.
  • Apply binary search on the possible answer range to get minimum speed to eat all bananas within k hours.
    • If the current speed (mid) is enough to eat all bananas within given k hours then update the minimum eating time and continue the search in lower half of the range to check for slower eating speeds.
    • Else search in upper half of the range as we need to increase the eating speed.
C++
#include <iostream>
#include <vector>
#include <algorithm> 

using namespace std;

// Function to check whether current speed is enough
bool check(vector<int>& arr, int mid, int k) {
    int hours = 0;
    for (int i = 0; i < arr.size(); i++) {
        hours += arr[i] / mid;

        // Add one more hour if some bananas are left
        if (arr[i] % mid != 0) {
            hours++;
        }
    }

    // Return true if total hours needed is within limit
    return hours <= k;
}

// Function to find the minimum eating speed
int kokoEat(vector<int>& arr, int k) {
    int lo = 1;
    int hi = *max_element(arr.begin(), arr.end());
    int res = hi;

    while (lo <= hi) {
        int mid = lo + (hi - lo) / 2;

        if (check(arr, mid, k)) {
            // Update result and try slower speed
            res = mid;       
            hi = mid - 1;
        } else {
             // Need faster speed
            lo = mid + 1;    
        }
    }

    return res;
}

int main() {
    vector<int> arr = {5, 10, 3};
    int k = 4;
    cout << kokoEat(arr, k) << endl;
    return 0;
}
Java
import java.util.Arrays;

class GfG {
    
    // Function to check whether mid speed is enough
    // to eat all piles of bananas under k hours
    static boolean check(int[] arr, int mid, int k) {
        int hours = 0;
        for (int i = 0; i < arr.length; i++) {
            hours += arr[i] / mid;
          
            // 1 extra hour to eat the remainder 
            // number of bananas in this pile
            if (arr[i] % mid != 0) {
                hours++;
            }
        }

        // return true if required time is less than 
        // or equals to given hour, otherwise return false
        return hours <= k;
    }

    static int kokoEat(int[] arr, int k) {
        
        // Minimum speed of eating is 1 banana/hours
        int lo = 1;

        // Maximum speed of eating is 
        // the maximum bananas in given piles
        int hi = Arrays.stream(arr).max().getAsInt();
        int res = hi;

        while (lo <= hi) {
            int mid = lo + (hi - lo) / 2;

            // Check if the mid(hours) is valid
            if (check(arr, mid, k) == true) {
              
                // If valid continue to search at
                // lower speed
                hi = mid - 1;
                res = mid;
            }
            else {
              
                // If cant finish bananas in given
                // hours, then increase the speed
                lo = mid + 1;
            }
        }
      
        return res;
    }

    public static void main(String[] args) {
        int[] arr = {5, 10, 3};
        int k = 4;
        System.out.println(kokoEat(arr, k));
    }
}
Python
# Function to check whether mid speed is enough
# to eat all piles of bananas under k hours
def check(arr, mid, k):
    hours = 0
    for i in range(len(arr)):
        hours += arr[i] // mid
      
        # 1 extra hour to eat the remainder 
        # number of bananas in this pile
        if arr[i] % mid != 0:
            hours += 1

    # return true if required time is less than 
    # or equals to given hour, otherwise return false
    return hours <= k

def kokoEat(arr, k):
    
    # Minimum speed of eating is 1 banana/hours
    lo = 1

    # Maximum speed of eating is 
    # the maximum bananas in given piles
    hi = max(arr)
    res = hi

    while lo <= hi:
        mid = lo + (hi - lo) // 2

        # Check if the mid(hours) is valid
        if check(arr, mid, k) == True:
          
            # If valid continue to search at
            # lower speed
            hi = mid - 1
            res = mid
        else:
          
            # If cant finish bananas in given
            # hours, then increase the speed
            lo = mid + 1
      
    return res

if __name__ == "__main__":
    arr = [5, 10, 3]
    k = 4
    print(kokoEat(arr, k))
C#
using System;
using System.Linq;

class GfG {
    // Function to check whether mid speed is enough
    // to eat all piles of bananas under k hours
    static bool check(int[] arr, int mid, int k) {
        int hours = 0;
        for (int i = 0; i < arr.Length; i++) {
            hours += arr[i] / mid;
          
            // 1 extra hour to eat the remainder 
            // number of bananas in this pile
            if (arr[i] % mid != 0) {
                hours++;
            }
        }

        // return true if required time is less than 
        // or equals to given hour, otherwise return false
        return hours <= k;
    }

    static int kokoEat(int[] arr, int k) {
        // Minimum speed of eating is 1 banana/hours
        int lo = 1;

        // Maximum speed of eating is 
        // the maximum bananas in given piles
        int hi = arr.Max();
        int res = hi;

        while (lo <= hi) {
            int mid = lo + (hi - lo) / 2;

            // Check if the mid(hours) is valid
            if (check(arr, mid, k) == true) {
              
                // If valid continue to search at
                // lower speed
                hi = mid - 1;
                res = mid;
            }
            else {
              
                // If cant finish bananas in given
                // hours, then increase the speed
                lo = mid + 1;
            }
        }
      
        return res;
    }

    static void Main() {
        int[] arr = {5, 10, 3};
        int k = 4;
        Console.WriteLine(kokoEat(arr, k));
    }
}
JavaScript
// Function to check whether mid speed is enough
// to eat all piles of bananas under k hours
function check(arr, mid, k) {
    let hours = 0;
    for (let i = 0; i < arr.length; i++) {
        hours += Math.floor(arr[i] / mid);
      
        // 1 extra hour to eat the remainder 
        // number of bananas in this pile
        if (arr[i] % mid !== 0) {
            hours++;
        }
    }

    // return true if required time is less than 
    // or equals to given hour, otherwise return false
    return hours <= k;
}

function kokoEat(arr, k) {
    // Minimum speed of eating is 1 banana/hours
    let lo = 1;

    // Maximum speed of eating is 
    // the maximum bananas in given piles
    let hi = Math.max(...arr);
    let res = hi;

    while (lo <= hi) {
        let mid = lo + Math.floor((hi - lo) / 2);

        // Check if the mid(hours) is valid
        if (check(arr, mid, k) === true) {
          
            // If valid continue to search at
            // lower speed
            hi = mid - 1;
            res = mid;
        }
        else {
          
            // If cant finish bananas in given
            // hours, then increase the speed
            lo = mid + 1;
        }
    }
  
    return res;
}

let arr = [5, 10, 3];
let k = 4;
console.log(kokoEat(arr, k));

Output
5

Time Complexity:  O(n log m), where m is the max bananas from all piles.
Auxiliary Space: O(1)
 


Next Article
Article Tags :
Practice Tags :

Similar Reads