传送带上的包裹必须在 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;
}
}
继上次写了到二分排序题后,我就发现但遇到有序的时候,就应该想想是否可以二分排序,
此题先要确定遍历区间的范围,即想要得到最佳的载重能力(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++;
i--;
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;剩余部分仿照上面