Loading...

二分查找新玩法-不在数组里找-而在-可能的答案-里找

在这里插入图片描述

求解思路

这道题我们可以把速度的范围确定在1到最大堆的香蕉数量之间,因为速度最小是1(总得吃),最大也不需要超过最大堆的数量(再快也没意义)。

然后我们在这个范围内不断尝试中间值,对于每个速度计算需要多少小时吃完,

如果小于等于h小时说明这个速度可行,但我们要找最小的,所以继续往左半边找更小的速度;

如果超过h小时说明速度太慢了,就往右半边找更快的速度。

这样不断缩小范围,最终就能找到刚好满足条件的最小速度。

代码解析

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public static int minEatingSpeed(int[] piles, int h) {
    // 确定速度的搜索范围[l,r]
    int l = 1;  // 最小速度为1
    int r = 0;
    for (int pile : piles) {
        r = Math.max(r, pile);  // 最大速度为最大堆的数量
    }
    
    // 在[l,r]区间内二分查找
    int ans = 0;
    int m = 0;
    while (l <= r) {
        m = l + ((r - l) >> 1);  // 计算中间速度,避免溢出
        
        if (f(piles, m) <= h) {
            // 当前速度可以在h小时内吃完
            ans = m;      // 记录答案
            r = m - 1;    // 尝试更小的速度
        } else {
            // 当前速度太慢,需要更快
            l = m + 1;
        }
    }
    return ans;
}

// 计算以speed速度吃完所有香蕉需要的小时数
public static long f(int[] piles, int speed) {
    long ans = 0;
    for (int pile : piles) {
        // 向上取整:(pile + speed - 1) / speed
        // 例如:pile=11,speed=4 → (11+3)/4=3小时
        ans += (pile + speed - 1) / speed;
    }
    return ans;
}

如果觉得有帮助,欢迎点赞、关注、转发~

最后更新于 2026-04-05 17:35:33
Code Road Record