在 D 天内送达包裹的能力
难度:
标签:
题目描述
代码结果
运行时间: 111 ms, 内存: 20.4 MB
/*
题目思路:
1. 使用流的方式来计算最大运载能力和总重量。
2. 其余逻辑与Java的解法相同。
*/
import java.util.Arrays;
public class Solution {
public int shipWithinDays(int[] weights, int days) {
int left = Arrays.stream(weights).max().getAsInt();
int right = Arrays.stream(weights).sum();
while (left < right) {
int mid = (left + right) / 2;
if (canShip(weights, days, mid)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
private boolean canShip(int[] weights, int days, int capacity) {
int currentLoad = 0;
int requiredDays = 1;
for (int w : weights) {
if (currentLoad + w > capacity) {
requiredDays++;
currentLoad = 0;
}
currentLoad += w;
}
return requiredDays <= days;
}
}
解释
方法:
该题解采用二分查找法确定最小的运载能力。首先设置二分查找的范围:下界 l 是 weights 中的最大值(因为载重至少要能承载单个包裹中的最大重量),上界 r 是按最大包裹权重均匀分布时的总重量。然后定义一个辅助函数 check(cap),用于判断给定的载重 cap 是否能在指定的 days 天内运送完所有包裹。具体方法是顺序累加包裹重量,当累加的重量超过 cap 时,需要使用新的一天继续装载,如果使用的天数超过 days,则返回 False。通过二分查找逐渐缩小可能的载重范围,直到找到最小的符合条件的载重。
时间复杂度:
O(n log(R-L))
空间复杂度:
O(1)
代码细节讲解
🦆
为什么在二分查找中下界设置为weights数组中的最大值?
▷🦆
在二分查找中,当check函数返回False时,为什么选择增加mid值(即设置l = m + 1)?
▷🦆
check函数在处理完所有weights后直接返回True是否考虑了所有边界情况,例如当最后一天刚好达到或略低于最大载重时的情况?
▷🦆
在实际应用中,如何确定weights数组中单个包裹的最大重量不会超过船的最大承载能力?
▷