数据结构刷题(10)二分搜索题型(python实现)

对于该问题,我们要求最小速度k,在最小速度k下计算吃完这一堆香蕉的时间:sum+=math.ceil(piles[i]/k) (根据题目要求,向上取整)

对于k,假设速度大于k,那么sum一定小于h,速度小于k,sum一定大于h

由此我们确定二分法雏形,吃一堆香蕉最快的速度是max(pile),因为题目中说每个小时会挑一堆来吃,就算提前吃完也不会吃下一堆,所以最快的速度是这一堆中最大的元素。最少也要在一个小时中吃一根,所以最小速度是1.

假设k = int((left+right)/2)

开始二分寻找最小k 值,代码如下:

class Solution:

    def minEatingSpeed(self, piles: List[int], h: int) -> int:

        right = max(piles)

        left = 1

        import math

        while left <= right: #循环跳出的条件应该是left>right,也就是这个区间都遍历完

            mid = int((left + right) / 2) 

            Sum = 0

            for i in piles:

                Sum += math.ceil(i / mid)

            if Sum > h:

                left = mid + 1

            if Sum <= h:

                right = mid - 1

        return left  #最后的left值是大于right和mid的

对于该题目的分析就是找到最小的装载能力k,船舶最大的装载能力high应该是sum(weights),也就是一天可以把全部货物送达。为了保证每天都有货物送达,船舶的最小装载能力应该是max(weights)。具体代码如下:

class Solution:

    def shipWithinDays(self, weights: List[int], days: int) -> int:

        high = sum(weights)

        low = max(weights)

        while low <= high:

            k = int((low+high)/2)

            Sum = 0 #装载量

            i = 0

            day = 0 #计算当前装载能力k下的运输天数

            while i< len(weights):

                Sum += weights[i]

                if Sum > k and 0 <= Sum - weights[i] <= k : #确保sum此时装载的数量一定大于船舶运输能力,减去此次的重量后小于等于船舶的运输能力,这样的装载量需要day++,并且不移动i

                    day += 1

                    Sum = 0

                elif Sum <= k and i == len(weights) -1 : #最后的几批货物总和一定是小于等于k的

                    day += 1

                    i += 1

                else:

                    i += 1

            if day <= days: #说明装载能力过强,需要向左移动区间,求最小值,等号放在high的移动区间上

                high = k - 1

            if day > days: #说明装载能力过弱,需要向右移动区间

                low = k + 1

        return low

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值