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 = 8
Output: 4
Explanation: Koko will eat 4 bananas per hour to finish all the bananasInput: piles = [30, 11, 23, 4, 20], H = 6
Output: 23
Explanation: 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 S
- If the boolean function satisfies the mid value reduce higher to mid
- Else update lower limit to mid + 1
// 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 code int 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 code public 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 approach def 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 code piles = [ 30 , 11 , 23 , 4 , 20 ];
H = 6 ;
print (minEatingSpeed(piles, H));
# This code is contributed by gfgking. |
// C# implementation for the above approach using 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 code public 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)