说实话要是不是因为这道题是归类在二分查找里面,我就只会暴力枚举了,所以算法思想真的很重要。先上题:
(题目截自LeetCode)
题目要求包裹要按顺序,而求的是最低运载能力,所以可以用二分查找船的运载能力,而且可以知道二分查找的范围便是单个包裹的最大重量和所有包裹的重量和。最后返回的是left而不是mid,因为求的是最低运载能力,就是合适范围内的最小值。还有要注意的就是在计算天数时,当加上后一个包裹重量超过运载能力时不能直接置0,而是置为后一个包裹的重量,而刚好等于运载能力时才能置为0,最后还要判断一下重量是否被置为0,如果不是的话,代表还有包裹未运过去,所以要再加一天。代码如下:
class Solution {
int fun(vector<int>& weights, int mid)
{
int day=0;
int weight=0;
for(int i=0;i<weights.size();i++)
{
if(weight+weights[i]==mid)
{
day++;
weight=0;
}
else if(weight+weights[i]>mid)
{
day++;
weight=weights[i];
}
else weight+=weights[i];
}
if(weight!=0)
day++;
return day;
}
public:
int shipWithinDays(vector<int>& weights, int D) {
int sum=0;
int maxw=0;
for(int i=0;i<weights.size();i++)
{
sum+=weights[i];
maxw=max(maxw,weights[i]);
}
int left=maxw;
int right=sum;
int mid;
while(left<right)
{
mid=left+(right-left)/2;
if(fun(weights,mid)>D)
left=mid+1;
else right=mid;
}
return left;
}
};
看了一下LeetCode题解里大佬们的写法,发现我又做了无用功,计算天数时,只要分为恰好等于和其他两种情况即可,等于则weight重置为0,否则weight+=weights[i];