leetcode:在D天内送包裹的能力

题目来源:力扣

题目描述:

传送带上的包裹必须在 D 天内从一个港口运送到另一个港口。
传送带上的第 i 个包裹的重量为 weights[i]。每一天,我们都会按给出重量的顺序往传送带上装载包裹。我们装载的重量不会超过船的最大运载重量。
返回能在 D 天内将传送带上的所有包裹送达的船的最低运载能力。

该题目与另一力扣习题吃香蕉类似,大家如果感兴趣可以比较一下.

审题:

1.题目中提到包裹必须按照先后顺序装载,因此我们很容易计算给定运载能力下,完成所有货物运输所需的时间.
2. 题目要求返回能在指定时间内完成所有包裹送达的船的最低运载能力.

由于之前做过类似的题目,如吃香蕉.因此题目做到这,我便想到了将这道题转化为在存在重复至条件下,使用二分搜索查找对应值的最小下标位置.

使用二分搜索我们需要确定搜索的上下边界,对于这道题,其运载能力下边界为最重的货物重量,因为如果运载能力小于最重的货物重量, 则该货物永远无法被运载.由于所需时间以日为单位,因此最少的运输时间为1日,对应的运载能力上界便是所有货物重量之和.

基于以上,我们算法实现如下节.

java算法实现:

class Solution {
    //计算运载能力为capacity时,运载完所有货物所需时间
    private int dayConsume(int[] weights, int capacity){
        int days = 0;
        int capacityRemain = capacity;
        for(int i = 0; i < weights.length; i++){
            if(capacityRemain < weights[i]){ //如果剩余容量不够装载当前货物,则当前货物及后序货物只能安排在下一日装载
                days++;
                capacityRemain = capacity; 
            }
            capacityRemain -= weights[i];
        }
        days++;
        return days;
    }

    //使用二分搜索
    public int shipWithinDays(int[] weights, int D) {
        int toatlWeights = 0;
        int maxWeight = 0;
        for(int i: weights){
            if(i > maxWeight)
                maxWeight = i;
            toatlWeights += i;
        }
        int lo = maxWeight;
        int hi = toatlWeights+1;

        while(lo < hi){
            int mid = lo + (hi-lo) / 2;
            int days = dayConsume(weights, mid);
            if(days <= D) //如果days <= D, 则可能的搜索范围包括[lo, mid], 如果在[lo, mid)内未搜索到,则返回mid 
                hi = mid;
            else //如果days > D, 则可能的搜索范围为[mid+1, hi)
                lo = mid+1;
        }
        return hi;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值