875. 爱吃香蕉的珂珂
珂珂喜欢吃香蕉。这里有 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 <= 10^4
piles.length <= H <= 10^9
1 <= piles[i] <= 10^9
思路
本题是278题(第一个错误版本)的变种。
搜索区间:该题的要求是返回在 H 小时内吃掉所有香蕉的最小速度,也就是速度是变量。考虑其最大值和最小值:
最小值:肯定就是 1。最大值:数组的最大值,保证每小时可以吃一堆,在 piles.length 小时内吃完
二分过程
其测试分布可能如下所示:
1 2 3 4 5 6 7 8F F F F T T T T *
如果珂珂能以 K
的进食速度最终吃完所有的香蕉(在 H
小时内),那么她也可以用更快的速度吃完。
当珂珂能以 K
的进食速度吃完香蕉时,我们令 possible(K)
为 true
,那么就存在 X
使得当 K >= X
时, possible(K) = True
。
举个例子,当初始条件为 piles = [3, 6, 7, 11]
和 H = 8
时,存在 X = 4
使得 possible(1) = possible(2) = possible(3) = False
,且 possible(4) = possible(5) = ... = True
。
所以该题的重点就是实现278题中的 isBadVersion()
函数。然后第一个 T
的位置。
吃香蕉
从题意可以知道,吃掉一堆香蕉的时间是 \((piles[i] - 1)/K 1\),考虑一下为什么这样写?
所以我们只需要根据给定的 K
计算出吃完所有香蕉的时间,然后与 H
相比较。返回给 possible()
函数即可,然后在 minEatingSpeed()
函数中缩小搜索空间,并尝试新的 K
值。
代码
class Solution {public: int possible(vector<int>& piles, int H, int K) { int time = 0; for (int i : piles) { time = time ((i - 1) / K 1); } return time <= H; } int minEatingSpeed(vector<int>& piles, int H) { int l = 1, r = pow(10, 9); while (l < r) { int mid = l (r - l) / 2; if (!possible(piles, H, mid)) { l = mid 1; } else { r = mid; } } return l; }};