【LC】875. 爱吃香蕉的珂珂
832
2022-02-26
珂珂喜欢吃香蕉。这里有 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 <= 104
piles.length <= H <= 109
1 <= piles[i] <= 10^9
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/koko-eating-bananas
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
痛点分析
这道题使用二分查找的基本思路是没有问题的。
其难点在于确定二分查找的范围,如果无脑用[1, max(piles)]
就出现超时的情况。
- 使用
piles
中最小元素(每小时最小消耗速度),计算得出总耗时。- 总耗时大于
h
,则说明花费的时间太长了需要加快速度,所以,此时可确定二叉查找的范围为[max(piles), max(piles)]
- 否则呢,说明花费的时间太短即速度太快,需要减缓速度,所以,可确定二叉查找范围为
[1, min(piles)]
。
- 总耗时大于
0x01
class Solution:
def minEatingSpeed(self, piles: List[int], h: int) -> int:
def helper(k):
s = 0
for p in piles:
# 优雅写法:s += (p + k - 1) // k
if p <= k:
s += 1
else:
s += math.ceil(p / k)
return s
# 关键在于二叉搜索范围的确定
minn, maxn = min(piles), max(piles)
if helper(minn) > h:
# 最小速度所消耗的时间大于H,太慢了,需要扩大消耗速度
left, right = minn, maxn
else:
left, right = 1, minn
while left < right:
k = (left + right) >> 1
if helper(k) > h:
# 耗时太快,则加快速度
left = k + 1
else:
# 耗时太短,则减慢速度
right = k
return left
- 0
- 0
-
分享