Leetcode 875. Koko Eating Bananas (Binary search 经典题)

文章讲述了Koko面临香蕉堆,要在守卫回来前吃完所有香蕉,要求找到在给定时间内吃得最慢但能吃完的最小速度。使用二分查找算法解决此问题,给出几个示例和时间复杂度分析。
  1. Koko Eating Bananas
    Medium
    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

解法1:经典binary search。注意即使某个解已经满足条件,比如时间刚好等于h,也不一定是最优解,因为可能比它小的速度也可以满足时间刚好等于h。
比如:
Input: piles = [3,6,7,11], h = 8
速度为5满足h=8,但最优速度为4。

class Solution {
public:
    int minEatingSpeed(vector<int>& piles, int h) {
        long long n = piles.size();
        long long start = 1, end = LLONG_MAX;
        while (start + 1 < end) {
            long long mid = start + (end - start) / 2;
            int hour = eatingHours(piles, mid) ;
            if (hour <= h) {
                end = mid;
            } else if (hour > h) {
                start = mid;
            } else {
                return mid;
            }
        }
        if (eatingHours(piles, start) <= h) return start;
        return end;
    }
private:
    // return # of hours Koko used to finish all the bananas with speed k
    // the higher k, the less the hours needed
    long long eatingHours(vector<int> piles, long long k) {
        long long res = 0;
        long long n = piles.size();
        for (int i = 0; i < n; i++) {
            res += piles[i] / k + (piles[i] % k > 0 ? 1 : 0);
        }
        return res;
    }
};
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值