Title:

Baboons like bananas. There are N piles of bananas and piles[i] bananas in pile I. The guard has left and will be back in H hours.

The baboon can determine the speed K (in roots / hour) at which she eats bananas. Every hour, she will choose a pile of bananas and eat K of them. If this pile of bananas is less than k, she will eat all the bananas in this pile, and then she will not eat more bananas in this hour, and she will start eating another pile of bananas in the next hour.

Baboons like to eat slowly, but they still want to eat all the bananas before the guards come back.

Returns the minimum speed K at which she can eat all bananas in H hours (k is an integer).

Input: piles = [3,6,7,11], H = 8

Output: 4

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

Output: 30

analysis:

Although I don't know how many bananas a baboon needs to eat in an hour before the guard comes back, I know the speed range of eating bananas. Obviously, the upper limit of the number of bananas it eats per hour is the maximum number of bananas in a pile, which is recorded as max.

The speed of baboons eating bananas should be within the range of the minimum value of 1 banana and the maximum value of Max root. Take the middle value of mid root at 1-max root, and calculate the time to eat all bananas at the speed of eating mid bananas per hour. If the time required is more than h hours, it means that they should eat faster. Therefore, the speed of baboons eating bananas should be within the range of mid+1 to max, If the required time is less than or equal to h hours, judge whether mid root is the slowest speed. The judgment method is to calculate how long it takes to eat mid-1 bananas per hour. If the speed of eating mid-1 bananas per hour is less than or equal to h hours, it means that mid-1 bananas per hour is not the slowest speed to eat all bananas in H hours. Therefore, the speed of baboons eating bananas should be between 1 and mid-1. If the time of eating all bananas at mid-1 bananas per hour is greater than h hours, It means that mid root is the slowest speed at which you can eat all bananas in H hours. This process is actually a binary search.

If there are m piles of bananas in total, n is the maximum number of bananas in a pile. minEatingSpeed performs a binary search in the range of 1 to N, and it needs to try o (log n) times. For each attempt, it is necessary to find the time to eat all bananas at a certain speed, that is, the getHours function. Therefore, the total time complexity is O (m logn).

See the code comments for specific operations.

code:

public class MinEatingSpeed { public static void main(String[] args) { MinEatingSpeed minEatingSpeed = new MinEatingSpeed(); int[] piles = {3,6,7,11}; int h = 8; int i = minEatingSpeed.minEatingSpeed(piles, 8); System.out.println(i); } public int minEatingSpeed(int[] piles, int h) { int max=Integer.MIN_VALUE; // Select the largest element in the array as the maximum number of bananas to eat per hour for (int pile : piles) { max = Math.max(pile,max); } // Eat at least one banana per hour and max bananas at most. The whole process is actually a binary search between 1 and max bananas. int left = 1; int right = max; while (left<=right){ int mid = (left+right)/2; // The total time spent is derived from the rate, and the getHours function is called int hours = getHours(piles,mid); // The target calculates the minimum rate. If the time spent at the mid rate is less than the target h, check whether the time at the mid-1 rate is less than the target H // If the time is greater than the target or mid=1, the mid-1 option is no longer available, indicating that the mid rate has reached the required minimum rate. If // If the above two conditions are not met, it indicates that the mid rate has not reached the required minimum rate, so find it in the left half area if (hours<=h){ if (mid == 1||getHours(piles,mid-1)>h){ return mid; } right = mid - 1; // If hours > H, it means that the rate mid meeting the requirements is found, and the rate is small, so find it in the right half area }else { left = mid + 1; } } return -1; } private int getHours(int[] piles, int mid) { int hours = 0; for (int pile : piles) { // Accumulate each element in the array divided by the upper bound of the rate to get the most common time // ceil(pile/mid) = (pile+mid-1)/mid. hours +=Math.ceil(pile*1.0/mid); // hours +=(pile+mid-1)/mid; } return hours; } }