中文描述:
珂珂喜欢吃香蕉。这里有 N 堆香蕉,第 i 堆中有 piles[i] 根香蕉。警卫已经离开了,将在 H 小时后回来。
珂珂可以决定她吃香蕉的速度 K (单位:根/小时)。每个小时,她将会选择一堆香蕉,从中吃掉 K 根。如果这堆香蕉少于 K 根,她将吃掉这堆的所有香蕉,然后这一小时内不会再吃更多的香蕉。
珂珂喜欢慢慢吃,但仍然想在警卫回来前吃掉所有的香蕉。
返回她可以在 H 小时内吃掉所有香蕉的最小速度 K(K 为整数)。
题目描述:
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 hour。
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
Constraints:
1 <= piles.length <= 104
piles.length <= h <= 109
1 <= piles[i] <= 109
Time complexity:
O
O
O(
N
N
Nlog(W)), where N is the number of piles, and W is the maximum size of a pile.
Space complexity:
O
O
O(
1
1
1)
二分 二分搜索总结:
根据上面的二分搜索总结,注意此题为 找最小速度 K 使得她可以在 H 小时内吃掉所有香蕉
则此题可以归纳为二分找左边界(最优区间的左边) 套用基础模版:
初始化左边界 lo:1。
初始化右边界 hi:constraints 中最大的数据范围 109。
循环条件: lo < hi
中间位置 mid = lo + (hi-lo>>1),
更新左边界 lo = mid+1,
更新右边界 hi = mid,
左右边界的判断条件:
注意更新左右边界的判断条件:当我们给定一个值 x,我们可以线性地验证是否存在一种方案,当她的速度为 x时 她仍然能在 H小时内吃完。
贪心地模拟分割的过程,从前到后遍历数组,用 time 表示当前所用的时间总和,每次我们求出当前这一堆 p 吃完所用的是间 即:t = Math.ceil(p / x) 向上取整 = (p-1) / x + 1,并将time 加 上 t。遍历结束后验证是否 time 不超过 H。
满足此条件的话则我们在 [lo, x(mid)] 的 范围内继续寻找是否存在更小的 x 值满足此条件 即 hi = mid。反之则表示给定的 速度x值过小 lo = mid + 1.
class Solution {
public int minEatingSpeed(int[] piles, int h) {
int lo = 1;
int hi = 1_000_000_000;
int mid;
while(lo < hi){
mid = lo + (hi-lo>>1);
if(check(piles, h, mid)){
// speed mid eat with in h hours
hi = mid;
}else{
lo = mid+1;
}
}
return lo;
}
private boolean check(int[] piles, int h, int x){
int time = 0;
for(int p:piles){
time += (p-1) / x + 1;
}
return time <= h;
}
}