题目:在 D 天内送达包裹的能力
传送带上的包裹必须在 D 天内从一个港口运送到另一个港口。
传送带上的第 i 个包裹的重量为 weights[i]。每一天,我们都会按给出重量的顺序往传送带上装载包裹。我们装载的重量不会超过船的最大运载重量。
返回能在 D 天内将传送带上的所有包裹送达的船的最低运载能力。
思路
以船容量为标定进行二分查找,最小船容量(左边界)为数组中的最大值,对应每天运输一条船;最大船容量(右边界)为数组和,对应一次都运输走的情况,用二分查找的模板(找一个模糊值的模板),注意搜索区域的缩减:如果当前船容量满足条件,缩减右边界,right=mid;如果当前船容量不满足条件,缩减左边界,left=mid+1
代码
class Solution {
public int shipWithinDays(int[] weights, int D) {
//以船容量进行二分查找,左边界为数组的最大值(对应每天一条船),右边界为数组的和(对应一条超级大船)
int sum=0;
int max=0;
for(int weight:weights){
sum+=weight;
max=Math.max(max,weight);
}
int left=max;
int right=sum;
while(left<right){
int mid=(left+right)/2;
if(isOk(weights,mid,D)){
right=mid;
}else{
left=mid+1;
}
}
return right;
}
private boolean isOk(int[]weights,int capacity,int D)//判断最大容量为capacity时能否在D天内装完
{
int curShip=0;
for(int w:weights){
if(curShip+w>capacity){
curShip=0;
D--;
}
curShip+=w;
}
return D>0;
}
}
复杂度分析
时间复杂度:O(nlogn)
空间复杂度:O(1)