Problem Statement:

Koko loves to eat bananas. There are n piles of bananas, the ith pile has piles[i] bananas. The guards have gone and will come back in h hours. Koko can decide her bananas-per-hour eating speed of k. Each hour, she chooses some pile of bananas and eats k bananas from that pile. If the pile has less than k bananas, she eats all of them instead and will not eat any more bananas during this hour. Koko likes to eat slowly but still wants to finish eating all the bananas before the guards return.

Return the minimum integer k such that she can eat all the bananas within h hours.

Example 1:

Input: piles = [3,6,7,11], h = 8 Output: 4

Example 2:

Input: piles = [30,11,23,4,20], h = 5 Output: 30

Example 3:

Input: piles = [30,11,23,4,20], h = 6 Output: 23

Solution:

The searchSpace consists of the rates at which koko can eat banana. Obviously, the minimum speed at which koko can eat banana is and max will the max bananas in array, i.e., .

class Solution {
    private boolean feasible(int[] piles, int h, int rate){
        int total = 0; //This will contain the total hours it took for koko to eat bananas.
 
        for(int pile: piles){
            // total += ((pile - 1) / rate) + 1; //Faster : Just another clever way to get the ceil
            int timeToEatPile = Math.ceil((double)pile / rate); //Time to eat one pile
            total += timeToEatPile//Slower
        }
        return total <= h;
    }
 
    public int minEatingSpeed(int[] piles, int h) {
        
        int maxRate = Integer.MIN_VALUE;
        for(int pile: piles){
            maxRate = Math.max(maxRate, pile);
        }
        
        int left = 1;
        int right = maxRate;
 
        while(left < right){
            int mid = left + (right - left)/2;
            if(feasible(piles, h, mid)){
                right = mid;
            } else{
                left = mid + 1;
            }
        }
        return left;
    }
}