文章目录
完成旅途的最少时间
题目描述:
给你一个数组 time ,其中 time[i] 表示第 i 辆公交车完成 一趟旅途 所需要花费的时间。
每辆公交车可以 连续 完成多趟旅途,也就是说,一辆公交车当前旅途完成后,可以 立马开始 下一趟旅途。每辆公交车 独立 运行,也就是说可以同时有多辆公交车在运行且互不影响。
给你一个整数 totalTrips ,表示所有公交车 总共 需要完成的旅途数目。请你返回完成 至少 totalTrips 趟旅途需要花费的 最少 时间。
题目链接:6010. 完成旅途的最少时间
示例1:
输入:time = [1,2,3], totalTrips = 5
输出:3
解释:
- 时刻 t = 1 ,每辆公交车完成的旅途数分别为 [1,0,0] 。
已完成的总旅途数为 1 + 0 + 0 = 1 。- 时刻 t = 2 ,每辆公交车完成的旅途数分别为 [2,1,0] 。
已完成的总旅途数为 2 + 1 + 0 = 3 。- 时刻 t = 3 ,每辆公交车完成的旅途数分别为 [3,1,1] 。
已完成的总旅途数为 3 + 1 + 1 = 5 。
所以总共完成至少 5 趟旅途的最少时间为 3 。
示例2:
输入:time = [2], totalTrips = 1
输出:2
解释:
只有一辆公交车,它将在时刻 t = 2 完成第一趟旅途。
所以完成 1 趟旅途的最少时间为 2 。
提示:
1 <= time.length <= 105
1 <= time[i], totalTrips <= 107
解题思路:
这道题我们采用二分的方法做,这个时候大家可能会问了为什么要采用二分去做呢?当我们读完题我们可以知道两个隐性的条件完成totalTrips趟旅途的最少时间是1(总共只需要完成一趟旅途,某辆公交车完成一趟旅途所需要花费的时间为1),完成totalTrips趟旅途的最长时间是在这些公交车中跑得最快的那辆公交车独自完成totalTrips趟旅途(这是我们的上界)那么这个时候我们就知道,要求完成totalTrips趟旅途的最少时间就等价于在[1,上界]中求完成totalTrips趟旅途的最少时间。
在写代码的时候我们先通过遍历一遍time数组找到跑得最快的那辆公交车,然后在[1,上界]进行二分。注意:我们这里的check函数是计算所有公交车在当前mid时间内能完成旅途次数的总和(count),如果我们发现count>=totalTrips,那么完成旅途的最少时间就在我们mid的左边并且包含mid,因此我们需要更新区间为[l,mid],反之如果发现count<totalTrips,则表示完成旅途的最少时间在我们mid的右边不包含mid,因此更新区间为[mid+1,r],当二分结束我们也就找到了完成totalTrips趟旅途的最少时间。
题目代码:
class Solution {
public:
bool check(vector<int>& time,int totalTrips,long long mid)
{
//用来记录在mid时间内完成旅途的趟数
long long count = 0;
for(int i = 0;i<time.size();i++)
{
//计算所有公交车在当前mid时间内能完成旅途次数的总和
count+=mid/time[i];
}
return count>=totalTrips;
}
long long minimumTime(vector<int>& time, int totalTrips) {
//完成totalTrip趟旅途需要的最长时间是:完成一趟旅途花费最少时间的公交车 独自完成totalTrip趟
long long miniti = INT_MAX;
for(auto& e:time)
{
if(e<miniti)
{
miniti = e;
}
}
//最小的时间为1
long long l = 1;
long long r = miniti*totalTrips;
while(l<r)
{
//防止溢出
long long mid = l+((r-l)>>1);
if(check(time,totalTrips,mid))
{
r = mid;
}
else
{
l = mid+1;
}
}
return l;
}
};