package com.dong.mytest.demo.other.yan.dianrong;
public class DianRongTest {
private static int execute(int[] parts, int lengthTime) {
// 总和
int sum = 0;
// 速度最大值为数组中的最大值(即就算是最大的一份,一分钟也能消耗完,其他的一分钟肯定也能消耗完,那么总时间就是总份数,即parts.length)
int maxSpeed = 0;
for (int part : parts) {
sum += part;
maxSpeed = Math.max(maxSpeed, part);
}
// 速度的最小值,总数除以时间,有余数就再+1
int minSpeed = sum / lengthTime;
int mod1 = sum % lengthTime;
if (mod1 > 0) {
minSpeed++;
}
System.out.println("minSpeed=" + minSpeed + ",maxSpeed=" + maxSpeed);
// 下面就在这个范围内取出满足规则的最小值,有两种方案:
// 1. 直接从小到大一个一个试,这种就是可能尝试的最大次数为 maxSpeed-minSpeed+1,复杂度为O(maxSpeed-minSpeed + 1)
// 2. 使用二分法,减少可能的排查次数
int start = minSpeed;
int end = maxSpeed;
int middle = 0;
// 最终结果,先直接初始化个最大值
int result = maxSpeed;
while (start <= end) {
System.out.println("start=" + start + ",end=" + end);
middle = start + ((end - start) / 2);
int sumTime = 0;
for (int part : parts) {
// 消耗这份需要花的时间,有余数就加1
sumTime += ((part / middle) + (part % middle > 0 ? 1 : 0));
}
System.out.println("middle=" + middle + ",sumTime=" + sumTime);
// 花的时间比给的时间长,则说明这个速度小了,需要向右半侧取
if (sumTime > lengthTime) {
start = middle + 1;
} else {
// 花的时间小于等于给的时间,说明满足,继续向左侧试还有没有更小的
end = middle - 1;
result = Math.min(result, middle);
}
}
return result;
}
public static void main(String[] args) {
// 5
System.out.println(execute(new int[]{1, 1, 1, 24}, 8));
System.out.println("========");
// 4
System.out.println(execute(new int[]{3, 6, 7, 11}, 8));
}
}