爱吃香蕉的狒狒
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 43 ms, 内存: 17.1 MB
/*
* 思路:
* 1. 使用二分查找法找到吃香蕉的最小速度K。
* 2. 初始化low为1(最小速度),high为piles中的最大值(最大速度)。
* 3. 每次计算mid(low和high的中间值),并检查以该速度吃完所有香蕉是否在H小时内完成。
* 4. 如果可以,则尝试更小的速度(high = mid);否则增加速度(low = mid + 1)。
* 5. 最终,low就是所需的最小速度。
*/
import java.util.Arrays;
public class Solution {
public int minEatingSpeed(int[] piles, int H) {
int low = 1;
int high = Arrays.stream(piles).max().getAsInt();
while (low < high) {
int mid = (low + high) / 2;
if (canFinish(piles, H, mid)) {
high = mid;
} else {
low = mid + 1;
}
}
return low;
}
private boolean canFinish(int[] piles, int H, int K) {
int hours = Arrays.stream(piles).map(pile -> (pile + K - 1) / K).sum();
return hours <= H;
}
}
解释
方法:
这个问题的核心是使用二分搜索来确定狒狒吃完所有香蕉的最小速度K。首先,定义一个辅助函数check(k),该函数用于验证以速度k是否可以在H小时内吃完所有香蕉。对于每堆香蕉,计算狒狒以速度k吃完它所需的小时数(向上取整),并累加所有堆所需的总小时数。如果总小时数小于等于H,返回真,否则返回假。然后,使用二分搜索在可能的速度范围内查找最小的K。速度的初始范围设置为从1到最大堆的香蕉数。二分搜索的逻辑是:如果中间速度mid可以在H小时内吃完所有香蕉,则尝试更小的速度区间;否则,尝试更大的速度区间。当左右边界相遇时,找到了最小的速度K。
时间复杂度:
O(N log M)
空间复杂度:
O(1)
代码细节讲解
🦆
为什么在二分搜索中使用`max(1, sum(piles) // h)`作为左边界?这个表达式的计算逻辑是什么?
▷🦆
二分搜索中,为什么将右边界设置为`max(piles)`,而不是更大的值?
▷🦆
在`check`函数中,为什么使用`ceil(num / k)`来计算吃完一堆香蕉所需的小时数,而不是直接使用`num / k`?
▷