题目简介:
给你一个数组 time
,其中 time[i]
表示第 i
辆公交车完成 一趟旅途 所需要花费的时间。
每辆公交车可以 连续 完成多趟旅途,也就是说,一辆公交车当前旅途完成后,可以 立马开始 下一趟旅途。每辆公交车 独立 运行,也就是说可以同时有多辆公交车在运行且互不影响。
给你一个整数 totalTrips
,表示所有公交车 总共 需要完成的旅途数目。请你返回完成 至少 totalTrips
趟旅途需要花费的 最少 时间。
解题方法:
首先我们排除特殊情况,只有一辆车,返回结果为time[0]*totalTrips。普遍情况中,我们可以通过设立时间界限,减小我们要搜寻的范围,根据题目可知,我们搜寻方案的时间一定小于最快车辆完成旅途时间,即min * totalTrips,在该范围内用check方法遍历每辆车可行驶旅途趟数。并且每次都使用二分法
复杂度:
时间:O(nlogM),其中 n 为 times长度,M上下界之间的差值。
空间复杂度:O(1)
public class question_2187 {
//二分法
public static void main(String[] args) {
int[] time = {69318,51095}; // 示例运输时间
int totalTrips = 42888; // 所需的总旅行次数
Solution_2187 solution2187 = new Solution_2187();
System.out.println(solution2187.minimumTime(time, totalTrips));
}
}
class Solution_2187 {
public long minimumTime(int[] time, int totalTrips) {
//只有一辆车
if(time.length == 1){
return (long)time[0]*totalTrips;
}
int min = time[0]; // 最小值
for (int t : time) {
if (t < min) {
min = t;
}
}
// 左右时间边界
long left = min - 1;
//注意对min*totalTrips强转,否则会造成整数溢出,导致部分用例出现错误
//如time =[69318,51095],totalTrips = 42888
long right = (long)min * totalTrips;
while (left <= right) { // 闭区间二分
long mid = (left + right) >> 1;
if (check(mid, time, totalTrips)) {
//永远符合的右时间边界,尝试更小的右时间边界
right = mid - 1;
} else {
//一直不符合,直到与right相等的左时间边界
left = mid + 1;
}
}
return left;
}
// 检查limit限制时间能否满足要求
private boolean check(long limit, int[] time, int totalTrips) {
long cnt = 0;
for (int t : time) {
cnt += limit / t;
if (cnt >= totalTrips) {
return true;
}
}
return false;
}
}