1011. 在 D 天内送达包裹的能力

传送带上的包裹必须在 D 天内从一个港口运送到另一个港口。

传送带上的第 i 个包裹的重量为 weights[i]。每一天,我们都会按给出重量的顺序往传送带上装载包裹。我们装载的重量不会超过船的最大运载重量。

返回能在 D 天内将传送带上的所有包裹送达的船的最低运载能力。

 

示例 1:

输入:weights = [1,2,3,4,5,6,7,8,9,10], D = 5
输出:15
解释:
船舶最低载重 15 就能够在 5 天内送达所有包裹,如下所示:
第 1 天:1, 2, 3, 4, 5
第 2 天:6, 7
第 3 天:8
第 4 天:9
第 5 天:10

请注意,货物必须按照给定的顺序装运,因此使用载重能力为 14 的船舶并将包装分成 (2, 3, 4, 5), (1, 6, 7), (8), (9), (10) 是不允许的。 
示例 2:

输入:weights = [3,2,2,4,1,4], D = 3
输出:6
解释:
船舶最低载重 6 就能够在 3 天内送达所有包裹,如下所示:
第 1 天:3, 2
第 2 天:2, 4
第 3 天:1, 4
示例 3:

输入:weights = [1,2,3,1,1], D = 4
输出:3
解释:
第 1 天:1
第 2 天:2
第 3 天:3
第 4 天:1, 1
 

提示:

1 <= D <= weights.length <= 50000
1 <= weights[i] <= 500
通过次数8,068提交次数15,285

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/capacity-to-ship-packages-within-d-days
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
class Solution {
    public int shipWithinDays(int[] weights, int D) {
         int sum=0;
        int left = -1;
        for(int weight:weights){
            sum+=weight;
            left = Math.max(left,weight);
        }
        int right=sum+1;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (canFinish(weights, D, mid)) {
                right = mid;
            } else {
                left = mid +1;
            }
        }
//        for(int i=left;i<right;i++){
//            if(canFinish(weights,D,i)){
//                return i;
//            }
//        }
        return left;
        // return sum;
    }
    private  boolean canFinish(int[] weights, int d, int load) {
        int day=0;
        int tempSum = load;
        for(int i=0;i<weights.length;i++){
            tempSum = tempSum - weights[i];
            if(tempSum<0){
                tempSum=load;
                day++;
                i--;
            }
        }
        day++;
        
        return day<=d;
    }
}
继上次写了到二分排序题后,我就发现但遇到有序的时候,就应该想想是否可以二分排序,
此题先要确定遍历区间的范围,即想要得到最佳的载重能力(load)从而能在指定时间完成任务,
很明显,当load等于全部的总和的时候,即可以在一天内全部载完,那么最小的范围呢应当是
所有重物内最大的那个值,只有保证至少能把最重的那个货物单独载完,才能达到要求,载完全部货物
(试想下,若所有货物中最重的那个有3kg,然而你的船最多只能承重2.9kg,那么这个3kg的货物就凉了,
你就无法完成任务了。也许有人会想到取其(所有货物的总重/天数) 得到平均值,
然而{1,2,3,1,1},D=4  平均为:8/4 = 2;那个3kg的重物就凉了,
不过我觉得可以求取平均值以及最大的那个值,取其中最大)
示例:{1,2,3,1,1} ,D=4 , left = 3(其中最大);right = 8(总和)
1)left = 3,right = 8
	left<right:
		mid = 5;
		 d = 4;tempSum = 5;day=0;
		   i=0;tempSum = tempSum-weight[0] = 4;
		   		4<0?false
		   i=1;tempSum = tempSum-weight[1] = 4-2=2
		   		2<0?false
		   i=2;tempSum = tempSum-weight[1] = 2-3=-1;
		   		-1<0?true
		   			day++;//今天就装了1kg,2kg的货物,此时day=1
		   			i--;//回退这个3kg的货物,下次再处理!!!。
		   			tempSum=load;//到第二天,船又回来了,又可以装货了
		   i=2;tempSum = tempSum-weight[2] = 5  - 3 = 2;
		   		2<0?false;
		   i=3;tempSum = tempSum-weight[3] = 2 - 1=1;
				1<0?false
			i=4;tempSum = tempSum-weight[4] = 1-1  0;
			0<0?false;
		循环结束,此时要注意,最后那个重物中tempSum = tempSum-weight[weight.length()-1],
		若tempSum<0,自然会进入if语句,加上一天,且回滚,但若减去后的tempSum>=0,就不会进入循环且直接结束了,此时tempSum = tempSum-weight[1]一定大于等于0因此可以通过直接给day加上一天完善;此时day = 2;
		return 2<=3;
	既然当船的载货能力在5是就可以在2天完成(原计划3天),那我就可以减小载货能力了以求达到3天的要求,那么left = 3;right = 5;
2)left<right
	mid = 4;剩余部分仿照上面
		
			
		 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值