leetcode:在 D 天内送达包裹的能力
2021-04-26 本文已影响0人
秃头哥编程
链接:https://leetcode-cn.com/problems/capacity-to-ship-packages-within-d-days/
我是按照这个思路来做的。
如果随便给一个船的运载重量,判断一下在D天内能否运完货物?
代码如下
/**
* nums 货物
* power 船的运载重量
* D 给定的天数
*/
private boolean check(int[] nums, int power, int D) {
// count表示船的运载能力为power时,运完所有货物需要的天数
// 注意count的初始值和返回值的对应关系
int count = 1, cap = power;
for (int num : nums) {
// 船剩下的运载量小于num货物的重量,需要放到下一天去运
if (num > cap) {
count++;
cap = power;
}
cap -= num;
}
return count <= D;
}
有了这个函数好办了。剩下的我们只需要确定一下在题目给的条件下,船可能的最大运载量和最小运载量,然后使用二分查找不断逼近最小值即可。
-
由于货物不可分割,那么至少每天需要运一个货物,可知船最小的运载量就是最重的那个货物的重量。
-
假设所有货物一天运完,可知船最大的运载量是所有货物重量之和。
确定了这两个数,就好办了,请看代码。
class Solution {
public int shipWithinDays(int[] weights, int D) {
// max表示不考虑其他因素,船的最低运载能力,即一天运一个货物,此时最低运载能力就是所有货物里最重的
// sum为货物的总重量,也是船的最大运载能力,即一天运完所有货物
int max = 0, sum = 0;
for (int weight : weights) {
max = Math.max(max, weight);
sum += weight;
}
int left = max, right = sum;
// 二分查找,不断查找直到找到在D天内能运完所有货物的最低运载能力
while (left < right) {
int mid = left + (right - left) / 2;
if (check(weights, mid, D)) {
right = mid;
} else {
left = mid + 1;
}
}
return right;
}
/**
* nums 货物
* power 船的运载重量
* D 给定的天数
*/
private boolean check(int[] nums, int power, int D) {
// count表示船的运载能力为power时,运完所有货物需要的天数
// 注意count的初始值和返回值的对于关系
int count = 1, cap = power;
for (int num : nums) {
// 船剩下的运载量小于num货物的重量,需要放到下一天去运
if (num > cap) {
count++;
cap = power;
}
cap -= num;
}
return count <= D;
}
}
image-20210426211208352.png