Koko Eating Bananas - GeeksforGeeks

27 Oct, 2021
Given N piles of bananas, the ith pile has piles[i] bananas and H hours time until guards return (N < H). Find the minimum (S) bananas to eat per hour such that Koko can eat all the bananas within H hours. Each hour, Koko chooses some pile of bananas and eats S bananas from that pile. If the pile has less than S bananas, then she consumes all of them, and won’t eat any more bananas during that hour. 
Examples:
Input: piles = [3, 6, 7, 11], H = 8Output: 4Explanation:  Koko will eat 4 bananas per hour to finish all the bananas
Input: piles = [30, 11, 23, 4, 20], H = 6Output: 23Explanation:  Koko will eat 23 bananas per hour to finish all the bananas
Naive Approach: Koko must eat at least one banana per hour. Let lower bound be start. The maximum number of bananas Koko can eat in one hour is the maximum number of bananas from all piles. This is the maximum possible value of S. Let upper bound ends. Having search interval from start to end and using linear search, for every value of S, it can be checked if this speed of eating bananas is valid or not. The first valid value of S will be the slowest speed and the desired answer.
Time Complexity: O(N * W), where W is maximum bananas from all piles 
Approach: Given problem can be solved efficiently by using binary search on answer technique:
Create a boolean function to check if the chosen speed (bananas/hour) is enough to eat all bananas within given H hours time or not
Lower limit of S is 1 banana/hr as Koko must eat one banana per hour, and Upper limit is the maximum bananas of all piles
Apply binary search on the possible answer range to get minimum value of SIf the boolean function satisfies the mid value reduce higher to midElse update lower limit to mid + 1
If the boolean function satisfies the mid value reduce higher to mid
Else update lower limit to mid + 1
C++
Java
Python3
C#
Javascript
// C++ implementation for the above approach #include <bits/stdc++.h>using namespace std; bool check(vector<int>& bananas, int mid_val, int H){    int time = 0;    for (int i = 0; i < bananas.size(); i++) {         // to get the ceil value        if (bananas[i] % mid_val != 0) {             // in case of odd number            time += ((bananas[i] / mid_val) + 1);        }        else {             // in case of even number            time += (bananas[i] / mid_val);        }    }     // check if time is less than    // or equals to given hour    if (time <= H) {        return true;    }    else {        return false;    }} int minEatingSpeed(vector<int>& piles, int H){     // as minimum speed of eating must be 1    int start = 1;     // Maximum speed of eating    // is the maximum bananas in given piles    int end = *max_element(piles.begin(), piles.end());     while (start < end) {        int mid = start + (end - start) / 2;         // Check if the mid(hours) is valid        if ((check(piles, mid, H)) == true) {             // If valid continue to search            // lower speed            end = mid;        }        else {            // If cant finish bananas in given            // hours, then increase the speed            start = mid + 1;        }    }    return end;} // Driver codeint main(){    vector<int> piles = { 30, 11, 23, 4, 20 };    int H = 6;    cout << minEatingSpeed(piles, H);    return 0;}
// Java implementation for the above approach  import java.util.*; class GFG{ static boolean check(int[] bananas, int mid_val, int H){    int time = 0;    for (int i = 0; i < bananas.length; i++) {         // to get the ceil value        if (bananas[i] % mid_val != 0) {             // in case of odd number            time += ((bananas[i] / mid_val) + 1);        }        else {             // in case of even number            time += (bananas[i] / mid_val);        }    }     // check if time is less than    // or equals to given hour    if (time <= H) {        return true;    }    else {        return false;    }} static int minEatingSpeed(int []piles, int H){     // as minimum speed of eating must be 1    int start = 1;     // Maximum speed of eating    // is the maximum bananas in given piles    int end = Arrays.stream(piles).max().getAsInt();     while (start < end) {        int mid = start + (end - start) / 2;         // Check if the mid(hours) is valid        if ((check(piles, mid, H)) == true) {             // If valid continue to search            // lower speed            end = mid;        }        else {            // If cant finish bananas in given            // hours, then increase the speed            start = mid + 1;        }    }    return end;} // Driver codepublic static void main(String[] args){    int []piles = { 30, 11, 23, 4, 20 };    int H = 6;    System.out.print(minEatingSpeed(piles, H));}} // This code is contributed by 29AjayKumar
# Python implementation for the above approachdef check(bananas, mid_val, H):  time = 0;  for i in range(len(bananas)):         # to get the ceil value    if (bananas[i] % mid_val != 0):             # in case of odd number      time += bananas[i] // mid_val + 1;    else:             # in case of even number      time += bananas[i] // mid_val   # check if time is less than  # or equals to given hour  if (time <= H):    return True;  else:    return False;   def minEatingSpeed(piles, H):  # as minimum speed of eating must be 1  start = 1;   # Maximum speed of eating  # is the maximum bananas in given piles  end = sorted(piles.copy(), reverse=True)[0]   while (start < end):    mid = start + (end - start) // 2;     # Check if the mid(hours) is valid    if (check(piles, mid, H) == True):             # If valid continue to search      # lower speed      end = mid;    else:             # If cant finish bananas in given      # hours, then increase the speed      start = mid + 1;  return end; # Driver codepiles = [30, 11, 23, 4, 20];H = 6;print(minEatingSpeed(piles, H)); # This code is contributed by gfgking.
// C# implementation for the above approachusing System;using System.Linq;public class GFG{ static bool check(int[] bananas, int mid_val, int H){    int time = 0;    for (int i = 0; i < bananas.Length; i++) {         // to get the ceil value        if (bananas[i] % mid_val != 0) {             // in case of odd number            time += ((bananas[i] / mid_val) + 1);        }        else {             // in case of even number            time += (bananas[i] / mid_val);        }    }     // check if time is less than    // or equals to given hour    if (time <= H) {        return true;    }    else {        return false;    }} static int minEatingSpeed(int []piles, int H){     // as minimum speed of eating must be 1    int start = 1;     // Maximum speed of eating    // is the maximum bananas in given piles    int end = piles.Max();     while (start < end) {        int mid = start + (end - start) / 2;         // Check if the mid(hours) is valid        if ((check(piles, mid, H)) == true) {             // If valid continue to search            // lower speed            end = mid;        }        else {            // If cant finish bananas in given            // hours, then increase the speed            start = mid + 1;        }    }    return end;} // Driver codepublic static void Main(String[] args){    int []piles = { 30, 11, 23, 4, 20 };    int H = 6;    Console.Write(minEatingSpeed(piles, H));}} // This code is contributed by shikhasingrajput
<script>// Javascript implementation for the above approach function check(bananas, mid_val, H) {  let time = 0;  for (let i = 0; i < bananas.length; i++) {    // to get the ceil value    if (bananas[i] % mid_val != 0) {      // in case of odd number      time += Math.floor(bananas[i] / mid_val) + 1;    } else {      // in case of even number      time += Math.floor(bananas[i] / mid_val);    }  }   // check if time is less than  // or equals to given hour  if (time <= H) {    return true;  } else {    return false;  }} function minEatingSpeed(piles, H) {  // as minimum speed of eating must be 1  let start = 1;   // Maximum speed of eating  // is the maximum bananas in given piles  let end = [...piles].sort((a, b) => b - a)[0];   while (start < end) {    let mid = start + Math.floor((end - start) / 2);     // Check if the mid(hours) is valid    if (check(piles, mid, H) == true) {      // If valid continue to search      // lower speed      end = mid;    } else {      // If cant finish bananas in given      // hours, then increase the speed      start = mid + 1;    }  }  return end;} // Driver code let piles = [30, 11, 23, 4, 20];let H = 6;document.write(minEatingSpeed(piles, H)); </script>
  
23
 
Time Complexity:  O(N log W) (W is the max bananas from all piles)Auxiliary Space: O(1)
 
29AjayKumar
gfgking
shikhasingrajput
Airbnb
Arrays
Greedy
Searching
Arrays
Searching
Greedy
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Count pairs with given sum
Chocolate Distribution Problem
Window Sliding Technique
Reversal algorithm for array rotation
Next Greater Element
Dijkstra's shortest path algorithm | Greedy Algo-7
Prim’s Minimum Spanning Tree (MST) | Greedy Algo-5
Kruskal’s Minimum Spanning Tree Algorithm | Greedy Algo-2
Write a program to print all permutations of a given string
Huffman Coding | Greedy Algo-3