LeetCode(1011 D天内运送包裹的能力)
程序员文章站
2022-04-25 20:22:17
...
如题
感觉没有捷径可找,只能确定需要迭代查找max元素到元素和之间的每个次数,找到最小的那一个
public static int shipWithinDays(int[] weights, int D) {
int sum =0;//元素和
int max =0;//最大元素
for(int i:weights) {
if(i>max) {
max=i;
}
sum+=i;
}
if(D>=weights.length) {//比元素个数都多那仅仅需要装下最大元素即可
return max;
}else if(D==1){
return sum;
}
for(int i=max;i<sum;i++) {//依次比较找出最合适的
if(test(i,weights,D)) {
return i;
}
}
return sum;
}
//判断载重量为m时是否可用d次运完
private static boolean test(int m, int[] weights, int d) {
int sum=0;
for(int i:weights) {
sum+=i;
if(sum>m) {
sum=i;
d--;
}
}
return d>-1;
}
结果很显然不是很理想
思路上找不到捷径了,但是很显然写法上可以优化,对于最小值的迭代,有最大值和最小值,很显然二分法减少迭代次数
public static int shipWithinDays1(int[] weights, int D) {
int sum =0;//元素和
int max =0;//最大元素
for(int i:weights) {
if(i>max) {
max=i;
}
sum+=i;
}
int isum =0;
int count =0;//计算载重为max的所需次数
for(int i:weights) {
isum+=i;
if(isum>max){
isum =i;
count++;
}
}
if(D>=count+1) {//count+1为容量为max时的需求次数,当次数大于等于该次数很显然只用返回max
return max;
}else if(D==1){
return sum;
}//后续使用二分法找出最合适的值
int in =max ; //二分法中的较小值
int ax =sum ;//二分法中的较大值
while (in<ax-1) { //注意退出条件 当差距为2时判断最后一次
if(test((in+ax)/2,weights,D)) {//平均值是能放下更新ax
ax = (in+ax)/2;
}else {//不成立时更新in
in = (in+ax)/2;
}
}
return ax;
}
优化效果很明显