本文涉及的基础知识点
C++二分查找
LeetCode2187. 完成旅途的最少时间
给你一个数组 time ,其中 time[i] 表示第 i 辆公交车完成 一趟旅途 所需要花费的时间。
每辆公交车可以 连续 完成多趟旅途,也就是说,一辆公交车当前旅途完成后,可以 立马开始 下一趟旅途。每辆公交车 独立 运行,也就是说可以同时有多辆公交车在运行且互不影响。
给你一个整数 totalTrips ,表示所有公交车 总共 需要完成的旅途数目。请你返回完成 至少 totalTrips 趟旅途需要花费的 最少 时间。
示例 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
二分查找
二分类型:寻找首端
Check参数范围:[1,1014]
Check函数: ( ∑ i : 0 n − 1 ( m i d / t i m e [ i ] ) ) > = t o t a l T r i p s (\sum_{i:0}^{n-1}(mid/time[i])) >= totalTrips (∑i:0n−1(mid/time[i]))>=totalTrips
代码
核心代码
template<class INDEX_TYPE>
class CBinarySearch
{
public:
CBinarySearch(INDEX_TYPE iMinIndex, INDEX_TYPE iMaxIndex):m_iMin(iMinIndex),m_iMax(iMaxIndex) {}
template<class _Pr>
INDEX_TYPE FindFrist( _Pr pr)
{
auto left = m_iMin - 1;
auto rightInclue = m_iMax;
while (rightInclue - left > 1)
{
const auto mid = left + (rightInclue - left) / 2;
if (pr(mid))
{
rightInclue = mid;
}
else
{
left = mid;
}
}
return rightInclue;
}
template<class _Pr>
INDEX_TYPE FindEnd( _Pr pr)
{
int leftInclude = m_iMin;
int right = m_iMax + 1;
while (right - leftInclude > 1)
{
const auto mid = leftInclude + (right - leftInclude) / 2;
if (pr(mid))
{
leftInclude = mid;
}
else
{
right = mid;
}
}
return leftInclude;
}
protected:
const INDEX_TYPE m_iMin, m_iMax;
};
class Solution {
public:
long long minimumTime(vector<int>& time, int totalTrips) {
auto Check = [&](long long mid) {
long long has = 0;
for (const auto& t : time) {
has += mid / t;
}
return has >= totalTrips;
};
return CBinarySearch<long long>(1, 1e14 + 1).FindFrist(Check);
}
};
单元测试
vector<int> time;
int totalTrips;
TEST_METHOD(TestMethod11)
{
time = { 1,2,3 }, totalTrips = 5;
auto res = Solution().minimumTime(time, totalTrips);
AssertEx(3LL, res);
}
TEST_METHOD(TestMethod12)
{
time = { 2 }, totalTrips = 1;
auto res = Solution().minimumTime(time, totalTrips);
AssertEx(2LL, res);
}
TEST_METHOD(TestMethod13)
{
time = { 10000000 }, totalTrips = 10000000;
auto res = Solution().minimumTime(time, totalTrips);
AssertEx(100000000000000LL, res);
}