Leetcode 875. 爱吃香蕉的珂珂

1.题目基本信息

1.1.题目描述

珂珂喜欢吃香蕉。这里有 n 堆香蕉,第 i 堆中有 piles[i] 根香蕉。警卫已经离开了,将在 h 小时后回来。

珂珂可以决定她吃香蕉的速度 k (单位:根/小时)。每个小时,她将会选择一堆香蕉,从中吃掉 k 根。如果这堆香蕉少于 k 根,她将吃掉这堆的所有香蕉,然后这一小时内不会再吃更多的香蕉。

珂珂喜欢慢慢吃,但仍然想在警卫回来前吃掉所有的香蕉。

返回她可以在 h 小时内吃掉所有香蕉的最小速度 k(k 为整数)。

1.2.题目地址

https://leetcode.cn/problems/koko-eating-bananas/description/

2.解题方法

2.1.解题思路

二分查找

2.2.解题步骤

第一步,判断是否可以用二分查找。因为吃的速度在1到max(piles)之间,且可以判断某个速度下是否能吃完,所以可以使用二分法。

第二步,理解红蓝染色法在该二分过程中的不变特征。红:check不能吃完,蓝:check能吃完;左闭右闭区间:left-1:始终指向红色,right+1始终指向蓝色;最终的left即为最小的能吃完的速度。

第三步,定义check的判断函数,如果速度是speed,那么吃完所有的香蕉需要的总时间即为每堆香蕉数除以速度并上取整的和,如果总时间小于等于h,则可以吃完,反之,吃不完。

第四步,根据check函数和左闭右闭的红蓝染色法二分模板进行编码获得最终的left,最终的left即为题解。

3.解题代码

Python代码

import math

# 二分查找
# 第一步,判断是否可以用二分查找。因为吃的速度在1到max(piles)之间,且可以判断某个速度下是否能吃完,所以可以使用二分法。
# 第二步,理解红蓝染色法在该二分过程中的不变特征。红:check不能吃完,蓝:check能吃完;左闭右闭区间:left-1:始终指向红色,right+1始终指向蓝色;最终的left即为最小的能吃完的速度。
# 第三步,定义check的判断函数,如果速度是speed,那么吃完所有的香蕉需要的总时间即为每堆香蕉数除以速度并上取整的和,如果总时间小于等于h,则可以吃完,反之,吃不完。
# 第四步,根据check函数和左闭右闭的红蓝染色法二分模板进行编码获得最终的left,最终的left即为题解。
class Solution:
    def minEatingSpeed(self, piles: List[int], h: int) -> int:
        # 红:check不能吃完,蓝:check能吃完;左闭右闭:left-1:始终指向红色,right+1始终指向蓝色;最终的left即为最小的能吃完的速度
        def check(speed):   # 返回是否能吃完
            sumHours=0
            for pile in piles:
                sumHours+=math.ceil(pile/speed)
            return sumHours<=h
        left,right=1,max(piles)
        while left<=right:
            mid=(right-left)//2+left
            if not check(mid):
                left=mid+1
            else:
                right=mid-1
        return left

C++代码

class Solution {
public:
    int minEatingSpeed(vector<int>& piles, int h) {
        int left=1;
        int right=*max_element(piles.begin(),piles.begin()+piles.size());
        while(left<=right){
            int mid=(right-left)/2+left;
            long long sumHours=0;
            for(int pile:piles){
                sumHours+=ceil(pile/double(mid));
            }
            if(sumHours>h){
                left=mid+1;
            }else{
                right=mid-1;
            }
        }
        return left;
    }
};

4.执行结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GEEK零零七

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值