Koko Eating Bananas

Last Updated : 12 Aug, 2025

Given an array arr[] where each element denotes the number of bananas in a pile, and an integer k representing the total number of hours available. In one hour, up to x bananas can be eaten from a single pile. If a pile contains fewer than x bananas, the entire pile is consumed in one hour. It is guaranteed that the number of piles is less than or equal to k.
Determine the minimum value of x such that all piles can be completed within k hours.

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.

Try it on GfG Practice
redirect icon

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

The idea is to try every possible eating speed from 1 to max(arr) and, for each speed, calculate the total time required to finish all piles.
For a given speed x, the time to finish a pile is (pile + x - 1) // x, and we sum this over all piles.
The smallest speed for which the total time is less than or equal to k is the required answer.

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

using namespace std;

int kokoEat(vector<int>& arr, int k) {
    
    int mx = *max_element(arr.begin(), arr.end());

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

        for (int i = 0; i < arr.size(); i++) {
            
            // add the time needed to eat this pile 
            // at the current speed
            reqTime += 
                (arr[i] + speed - 1) / speed;
        }

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


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 reqTime = 0;
            for (int i = 0; i < arr.length; i++) {
              
                // time required to eat this pile 
                // of bananas at current speed
                reqTime += (arr[i] + speed - 1) / speed;
            }
            
            // if total eating time at current speed
            // is smaller than given time
            if (reqTime <= 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):
      
        reqTime = 0
        for i in range(len(arr)):
          
            # time required to eat this pile 
            # of bananas at current speed
            reqTime += \
                (arr[i] + speed - 1) // speed
        
        # if total eating time at current speed
        # is smaller than given time
        if reqTime <= 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 reqTime = 0;
            for (int i = 0; i < arr.Length; i++) {
              
                // time required to eat this pile 
                // of bananas at current speed
                reqTime += 
                    (arr[i] + speed - 1) / speed;
            }
            
            // if total eating time at current speed
            // is smaller than given time
            if (reqTime <= 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 reqTime = 0;
        for (let i = 0; i < arr.length; i++) {
          
            // time required to eat this pile 
            // of bananas at current speed
            reqTime += 
                Math.floor((arr[i] + speed - 1) / speed);
            
        }
      
        // if total eating time at current speed
        // is smaller than given time
        if (reqTime <= k) {
            return speed;
        }
    }
  
    return mx;
}

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

Output
5

[Expected Approach] Using Binary Search on Answer

The core idea is to use binary search on the answer—specifically, on the eating speed x. For a given speed x, we can compute how many hours it would take to eat all the piles. This function is monotonic because -

  • As x increases, the total time required decreases or stays the same.
  • Therefore, if a certain speed x allows completion within k hours, any higher speed will also work

This monotonic behavior allows us to apply binary search to efficiently find the minimum valid speed.

Step by Step Implementation:

  • Initialize the binary search range:
    => Set low = 1 because the minimum possible eating speed is 1 banana per hour.
    => Set high = max(arr) since Koko never needs to eat faster than the largest pile.
    => Initialize a variable answer to store the minimum valid speed found.
  • Start binary search loop: While low <= high:
    => Calculate the middle speed: mid = (low + high) // 2
    - Initialize totalHours = 0
    - Loop through each pile in arr: For each pile, compute time required as (pile + mid - 1) // mid, add this time to totalHours
  • Decision based on total hours:
    => If totalHours <= k, then mid is a valid speed: Store mid in answer (it could be the minimum) and reduce the search space to the left half: high = mid - 1
    => If totalHours > k, then mid is too slow: Shift search to the right half: low = mid + 1
  • After the loop ends, answer contains the minimum speed that allows finishing all piles within k hours.
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 totalHours = 0;
    for (int i = 0; i < arr.size(); i++) {
        totalHours += (arr[i] + mid - 1) / mid;
    }

    // return true if total hours needed is within limit
    return totalHours <= 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 totalHours = 0;
        for (int i = 0; i < arr.length; i++) {
            totalHours += (arr[i] + mid - 1) / mid;
        }

        // return true if required time is less than 
        // or equals to given hour, otherwise return false
        return totalHours <= 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):
    totalHours = 0
    for i in range(len(arr)):
        totalHours += (arr[i] + mid - 1) // mid

    # return true if required time is less than 
    # or equals to given hour, otherwise return false
    return totalHours <= 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 totalHours = 0;
        for (int i = 0; i < arr.Length; i++) {
            totalHours += (arr[i] + mid - 1) / mid;
        }
        // return true if required time is less than 
        // or equals to given hour, otherwise return false
        return totalHours <= 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 totalHours = 0;
    for (let i = 0; i < arr.length; i++) {
        totalHours += Math.floor((arr[i] + mid - 1) / mid);
    }

    // return true if required time is less than 
    // or equals to given hour, otherwise return false
    return totalHours <= 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;
}

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

Output
5

Time Complexity: O(n × log m), binary search runs in O(log m) time, where m is the maximum pile size. For each candidate speed, we compute the total hours by iterating over all n piles, giving O(n) work per step.
Auxiliary Space: O(1)

Comment