思路:
- 用每小时吃香蕉的个数(即吃的速度)来做二分;
- 以当前速度能在警卫回来前吃完香蕉,表示当前速度是达标的;
- 若当前速度达标,尝试吃慢一点(每小时少吃一根),若减速后时间超标,表示当前速度就是最慢的速度;
- 若当前速度不达标,则要吃快一点,加速。
class Solution {
public:
int minEatingSpeed(vector<int>& piles, int h) {
//C++STL中的vector库自带取最大值的方法,不过返回的是指针,所以要对其取地址
int maxVal = *max_element(piles.begin(), piles.end());
//最慢的速度是一次吃一根,最快的速度是一次吃完最大的一堆香蕉
int left = 1, right = maxVal;
while (left <= right)
{
int mid = (left +right) >> 1;
int hours = getHours(piles, mid);
if (hours <= h) //当前速度达标
{
//尝试再吃慢一点,如果超出时间范围,则当前速度就是最慢速度
if (mid == 1 || getHours(piles, mid - 1) > h)
{
return mid;
}
right = mid - 1; //吃得太快了,需要吃慢一点
}
else
{
left = mid + 1; //吃得太慢了,需要吃快一点
}
}
return -1;
}
//计算在指定速度下,吃完所有香蕉的耗时
int getHours(vector<int>& piles, int speed)
{
int hours = 0;
for (int& pile :piles)
{
hours += (pile - 1) / speed + 1; //向上取整算法
}
return hours;
}
};
咦,对的,你这么写确实更简洁直观一点!