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 bananas
Input: 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++
#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++) {
if (bananas[i] % mid_val != 0) {
time += ((bananas[i] / mid_val) + 1);
}
else {
time += (bananas[i] / mid_val);
}
}
if ( time <= H) {
return true ;
}
else {
return false ;
}
}
int minEatingSpeed(vector< int >& piles, int H)
{
int start = 1;
int end = *max_element(piles.begin(), piles.end());
while (start < end) {
int mid = start + (end - start) / 2;
if ((check(piles, mid, H)) == true ) {
end = mid;
}
else {
start = mid + 1;
}
}
return end;
}
int main()
{
vector< int > piles = { 30, 11, 23, 4, 20 };
int H = 6;
cout << minEatingSpeed(piles, H);
return 0;
}
|
Java
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++) {
if (bananas[i] % mid_val != 0 ) {
time += ((bananas[i] / mid_val) + 1 );
}
else {
time += (bananas[i] / mid_val);
}
}
if (time <= H) {
return true ;
}
else {
return false ;
}
}
static int minEatingSpeed( int []piles, int H)
{
int start = 1 ;
int end = Arrays.stream(piles).max().getAsInt();
while (start < end) {
int mid = start + (end - start) / 2 ;
if ((check(piles, mid, H)) == true ) {
end = mid;
}
else {
start = mid + 1 ;
}
}
return end;
}
public static void main(String[] args)
{
int []piles = { 30 , 11 , 23 , 4 , 20 };
int H = 6 ;
System.out.print(minEatingSpeed(piles, H));
}
}
|
Python3
def check(bananas, mid_val, H):
time = 0 ;
for i in range ( len (bananas)):
if (bananas[i] % mid_val ! = 0 ):
time + = bananas[i] / / mid_val + 1 ;
else :
time + = bananas[i] / / mid_val
if (time < = H):
return True ;
else :
return False ;
def minEatingSpeed(piles, H):
start = 1 ;
end = sorted (piles.copy(), reverse = True )[ 0 ]
while (start < end):
mid = start + (end - start) / / 2 ;
if (check(piles, mid, H) = = True ):
end = mid;
else :
start = mid + 1 ;
return end;
piles = [ 30 , 11 , 23 , 4 , 20 ];
H = 6 ;
print (minEatingSpeed(piles, H));
|
C#
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++) {
if (bananas[i] % mid_val != 0) {
time += ((bananas[i] / mid_val) + 1);
}
else {
time += (bananas[i] / mid_val);
}
}
if (time <= H) {
return true ;
}
else {
return false ;
}
}
static int minEatingSpeed( int []piles, int H)
{
int start = 1;
int end = piles.Max();
while (start < end) {
int mid = start + (end - start) / 2;
if ((check(piles, mid, H)) == true ) {
end = mid;
}
else {
start = mid + 1;
}
}
return end;
}
public static void Main(String[] args)
{
int []piles = { 30, 11, 23, 4, 20 };
int H = 6;
Console.Write(minEatingSpeed(piles, H));
}
}
|
Javascript
<script>
function check(bananas, mid_val, H) {
let time = 0;
for (let i = 0; i < bananas.length; i++) {
if (bananas[i] % mid_val != 0) {
time += Math.floor(bananas[i] / mid_val) + 1;
} else {
time += Math.floor(bananas[i] / mid_val);
}
}
if (time <= H) {
return true ;
} else {
return false ;
}
}
function minEatingSpeed(piles, H) {
let start = 1;
let end = [...piles].sort((a, b) => b - a)[0];
while (start < end) {
let mid = start + Math.floor((end - start) / 2);
if (check(piles, mid, H) == true ) {
end = mid;
} else {
start = mid + 1;
}
}
return end;
}
let piles = [30, 11, 23, 4, 20];
let H = 6;
document.write(minEatingSpeed(piles, H));
</script>
|
Time Complexity: O(N log W) (W is the max bananas from all piles)
Auxiliary Space: O(1)
Last Updated :
27 Oct, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...