题目介绍
珂珂喜欢吃香蕉。这里有 n 堆香蕉,第 i 堆中有 piles[i] 根香蕉。警卫已经离开了,将在 h 小时后回来。
珂珂可以决定她吃香蕉的速度 k (单位:根/小时)。每个小时,她将会选择一堆香蕉,从中吃掉 k 根。如果这堆香蕉少于 k 根,她将吃掉这堆的所有香蕉,然后这一小时内不会再吃更多的香蕉。
珂珂喜欢慢慢吃,但仍然想在警卫回来前吃掉所有的香蕉。
返回她可以在 h 小时内吃掉所有香蕉的最小速度 k(k 为整数)。
示例1:
输入:piles = [3,6,7,11], h = 8 输出:4
示例2:
输入:piles = [30,11,23,4,20], h = 5 输出:30
示例3:
输入:piles = [30,11,23,4,20], h = 6 输出:23
提示
1 <= piles.length <= 104
piles.length <= h <= 109
1 <= piles[
i] <= 109
解题思路
二分查找法
public static void main(String[] args) {
int[] piles = {3, 6, 7, 11};
int speed = minEatingSpeed(piles, 8);
System.out.println(speed);
}
public static int minEatingSpeed(int[] piles, int h) {
// 找到最大堆的香蕉
int maxValue = 1;
for (int pile : piles) {
maxValue = Math.max(pile, maxValue);
}
// 速度最小的时候
int left = 1;
// 速度最大的时候
int right = maxValue;
// 在最小速度小于最大速度时
while (left < right) {
// 每堆香蕉吃完的耗时 = 这堆香蕉的数量 / 珂珂一小时吃香蕉的数量
int mid = left + (right - left) / 2;
if (calculateSum(piles, mid) > h) {
// 耗时太多,说明速度太慢,下一个搜索区间是[mid + 1 ..right]
left = mid + 1;
} else {
right = mid;
}
}
return left;
}
/**
* 如果返回的小时数大于H,则不符合题意
*
* @param piles 香蕉堆
* @param mid
* @return 需要的小时数
*/
private static int calculateSum(int[] piles, int mid) {
int sum = 0;
for (int pile : piles) {
// 进行上取整
sum += (pile + mid - 1) / mid;
}
return sum;
}