【leetcode】875. Koko Eating Bananas
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
Constraints:
1 <= piles.length <= 104
piles.length <= h <= 109
1 <= piles[i] <= 109
koko喜欢吃香蕉,一个小时能吃k个香蕉,且每次只会在一个位置吃香蕉,如果在当前位置吃完了香蕉,必须会满一个小时之后再去下一个地方吃香蕉,且要求吃完香蕉的总时间不超过h小时,求k的最小值。
对于这道题,比较直观的方法是,暴力法,从k等于1开始,然后计算吃完所有香蕉的时间,第一个满足时间要求的就是需要的k,这样代码好些但是时间复杂度是o(n^2)。内外有两层循环,直接超时了。
class Solution {
public:
int minEatingSpeed(vector<int>& piles, int h) {
sort(piles.begin(),piles.end());
int n=piles.size();
int min_piles=1;
int max_piles=piles[n-1];
int k=min_piles;
while(k<=max_piles){
int time=0;
for(auto pp:piles){
float zz=(float)pp;
time+=ceil(zz/k);
if(time>h) break;
}
if(time<=h) break;
k++;
}
return k;
}
};
对于一个超时的程序,在检索k的过程中可以考虑考虑利用二分法。首先随便猜一个中位数k,然后逼近上下限。这样外层的o(n)检索方式就变为了o(logn),整体的复杂度就为o(nlogn),这样就不超时了。
class Solution {
public:
int minEatingSpeed(vector<int>& piles, int h) {
sort(piles.begin(),piles.end());
int n=piles.size();
int low = 1, high = piles[n-1], k = 0;
while (low <= high) {
k = (low + high) / 2;
int h_ = 0;
for (int i = 0; i < piles.size(); i ++) {
h_ += ceil(1.0*piles[i] / k);// 不用(float)强转 直接×1.0
if(h_>h) break;
}
if (h_ > h)
low = k + 1;
else
high = k - 1;
}
return low;
}
};