这题和leetcode875题思路一致,都是使用二分查找求左边界问题,我们设定运载能力范围为[最大包裹重量,所有包裹重量之和],然后利用左边界搜索算法寻找最小运载能力值
左闭右闭区间搜索法:
int shipWithinDays(vector<int>& weights, int days) {
int left=0;
int right=0;
for(int w:weights){
left=max(left,w);
right+=w;
}
while(left<=right){
int mid=left+(right-left)/2;
if(f(weights,mid)<=days){
right=mid-1;
}else{
left=mid+1;
}
}
return left;
}
int f(vector<int>& weights,int x){
int days=0;
for(int i=0;i<weights.size();){//没有i++,因为不是每天只装一种货
int capcity=x;
while(i<weights.size()){
if(capcity<weights[i]) break;
else capcity-=weights[i];
i++;
}
days++;
}
return days;
}
左闭右开区间搜索法:
int shipWithinDays(vector<int>& weights, int days) {
int left=0;
int right=1;
for(int w:weights){
left=max(left,w);
right+=w;
}
while(left<right){
int mid=left+(right-left)/2;
if(f(weights,mid)<=days){
right=mid;
}else{
left=mid+1;
}
}
return left;
}
int f(vector<int>& weights,int x){
int days=0;
for(int i=0;i<weights.size();){//没有i++,因为不是每天只装一种货
int capcity=x;
while(i<weights.size()){
if(capcity<weights[i]) break;
else capcity-=weights[i];
i++;
}
days++;
}
return days;
}
本题要注意两种形式代码框架的区别:
1.左闭右闭区间搜索法里,初始化right=0,而左闭右开区间搜索法里,初始化right=1
2.while括号里一个是left <= right,一个是left < right
3.if里一个是right=mid-1,一个是right=mid
关于左闭右闭、左闭右开区间搜索法;二分查找寻找左边界、二分查找寻找右边界问题详述请看我的专栏:算法之二分查找理论(三种问题类型、两种算法形式)