英文原文
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
中文题目
珂珂喜欢吃香蕉。这里有 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
通过代码
官方题解
方法:二分查找
思路
如果珂珂能以 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
。
算法
我们可以二分查找 possible(K)
的值来找到第一个使得 possible(X)
为 True
的 X
:这将是我们的答案。我们的循环中,不变量 possible(hi)
总为 True
, lo
总小于等于答案。有关二分查找的更多信息,请参阅《力扣探索:二分查找》。
为了找到 possible(K)
的值, (即珂珂
是否能以 K
的进食速度在 H
小时内吃完所有的香蕉),我们模拟这一情景。对于每一堆(大小 p > 0
),我们可以推断出珂珂将在 Math.ceil(p / K) = ((p-1) // K) + 1
小时内吃完这一堆,我们将每一堆的完成时间加在一起并与 H
进行比较。
class Solution {
public:
int minEatingSpeed(vector<int>& piles, int H) {
int lo = 1, hi = pow(10, 9);
while (lo < hi) {
int mi = lo + (hi - lo) / 2;
if (!possible(piles, H, mi))
lo = mi + 1;
else
hi = mi;
}
return lo;
}
// Can Koko eat all bananas in H hours with eating speed K?
bool possible(vector<int>& piles, int H, int K) {
int time = 0;
for (int p: piles)
time += (p - 1) / K + 1;
return time <= H;
}
};
class Solution {
public int minEatingSpeed(int[] piles, int H) {
int lo = 1;
int hi = 1_000_000_000;
while (lo < hi) {
int mi = (lo + hi) / 2;
if (!possible(piles, H, mi))
lo = mi + 1;
else
hi = mi;
}
return lo;
}
// Can Koko eat all bananas in H hours with eating speed K?
public boolean possible(int[] piles, int H, int K) {
int time = 0;
for (int p: piles)
time += (p-1) / K + 1;
return time <= H;
}
}
class Solution(object):
def minEatingSpeed(self, piles, H):
# Can Koko eat all bananas in H hours with eating speed K?
def possible(K):
return sum((p-1) / K + 1 for p in piles) <= H
lo, hi = 1, max(piles)
while lo < hi:
mi = (lo + hi) / 2
if not possible(mi):
lo = mi + 1
else:
hi = mi
return lo
复杂度分析
时间复杂度:$O(N \log W)$,其中 $N$ 是香蕉堆的数量,$W$ 最大的香蕉堆的大小。
空间复杂度:$O(1)$。
统计信息
通过次数 | 提交次数 | AC比率 |
---|---|---|
49565 | 102883 | 48.2% |
提交历史
提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
---|
相似题目
题目 | 难度 |
---|---|
最小化去加油站的最大距离 | 困难 |