力扣【2187-完成旅途的最少时间】【数组-C语言实现】

题目:

1)给你一个数组 time ,其中 time[i] 表示第 i 辆公交车完成 一趟旅途 所需要花费的时间。

2)每辆公交车可以 连续 完成多趟旅途,也就是说,一辆公交车当前旅途完成后,可以 立马开始 下一趟旅途。每辆公交车 独立 运行,也就是说可以同时有多辆公交车在运行且互不影响。

3)给你一个整数 totalTrips ,表示所有公交车 总共 需要完成的旅途数目。请你返回完成 至少 totalTrips 趟旅途需要花费的 "最少" 时间。

题解:

注意以下几点:

(1)各车一趟花费的时间(time[i])可能相同也可能不相同,若跑一趟时间花费最长的一辆车来完成全部任务(totalTrips),则花费时间最多(设置为T)

(2)全部车辆从0时刻开始就出发,每走过一个时刻检测当前所有车辆是否已经完成一趟,并累计趟数,直到等于totalTrips,这时时间最少,但这种"顺序时间方向"来求最少时间,时间复杂度很高

(3)在上面(2)的基础上逆向思考,已经知到完成任务最多花费时间T,而最少时间是1(当time中只有一辆车且花费时间是1,而totalTrips=1时),因此在1~T这段时间内,采用分查找算法,每次找到一个时间midtime,然后检测从0时刻走到midtime这段时间内,所有车辆完成的趟数,并求和,若和大于totalTrips,用一个变量记录这个时间 ,然后继续寻找到合适的midtime(中间会不断更新变量记录的时间)时间,变量记录的时间就是所求的结果。

代码

cpp 复制代码
// 检测t时刻,time中所有车辆跑的次数总和
// (注意:车辆是独立的,只有每辆车都从0时刻开始出发,每到下一个时刻t,重新计算总共完成的趟数
bool check(long long t, int* time, int timeSize, int totalTrips) {
    long long tNum = 0; // 趟数
    for (int i = 0; i < timeSize; i++) {
        tNum += t / time[i]; // 计算所有车辆t时刻完成的趟数并累计求和,例:某一个辆车花费时间是2,当t=5时,该车完成t/2趟
    }
    return tNum >= totalTrips;
}
long long minimumTime(int* time, int timeSize, int totalTrips) {
    // 完成任务需要时间,最少也是1个单位时间
    long long lowtime = 1;
    // 完成任务所需最长时间,一开始默认是第一辆车单独跑完totalTrips趟次的任务时间
    long long hightime = (long long)time[0] * totalTrips;
    // 遍历数组time,获取所有车辆中完成totalTrips趟数的最长时间,在这段时间内任何车辆组合或单独都可完成任务
    for (int i = 1; i < timeSize; i++) {
        long long cur = (long long)time[i] * totalTrips;
        if (hightime < cur) {
            hightime = cur;
        }
    }
    // 二分的过程中,mid每次作为lowtime~hightime时间段的中间(mid奇偶性不影响)时刻,
    // 通过check函数判断时间走过mid个单位时,全部公交车跑了多少趟,若完成的趟数总和依然大于等于totalTrips,置hightime= mid
    while (lowtime < hightime) {
        long long midtime = (lowtime + hightime) / 2;
        if (check(midtime , time, timeSize, totalTrips)) {
            // 为了保证hightime始终指向一个时间,这段时间可以是最少时间,恰好完成任务,
            // 也可以超过totalTrips,当循环退出时,hightime就是最少时间
            hightime = midtime ;
        } else {
            lowtime = midtime + 1;
        }
    }
    return hightime;
}

时间复杂度:
O ( n l o g ( m k ) ) O(nlog(mk)) O(nlog(mk)),其中 n 为 time 数组的长度,m=totalTrips,k 为 time 中元素的最大值。我们总共需要进行 O(log(mk)) 次二分查找,每次判断完成旅途数目是否达到要求的时间复杂度均为 O(n)。

空间复杂度: O(1)

相关推荐
AI+程序员在路上4 小时前
CANopen 协议:介绍、调试命令与应用
linux·c语言·开发语言·网络
2401_831824964 小时前
基于C++的区块链实现
开发语言·c++·算法
We་ct4 小时前
LeetCode 918. 环形子数组的最大和:两种解法详解
前端·数据结构·算法·leetcode·typescript·动态规划·取反
愣头不青4 小时前
238.除了自身以外数组的乘积
数据结构·算法
爱编码的小八嘎4 小时前
C语言完美演绎4-4
c语言
人工智能AI酱4 小时前
【AI深究】逻辑回归(Logistic Regression)全网最详细全流程详解与案例(附大量Python代码演示)| 数学原理、案例流程、代码演示及结果解读 | 决策边界、正则化、优缺点及工程建议
人工智能·python·算法·机器学习·ai·逻辑回归·正则化
WangLanguager4 小时前
逻辑回归(Logistic Regression)的详细介绍及Python代码示例
python·算法·逻辑回归
m0_518019484 小时前
C++与机器学习框架
开发语言·c++·算法
一段佳话^cyx4 小时前
详解逻辑回归(Logistic Regression):原理、推导、实现与实战
大数据·算法·机器学习·逻辑回归
qq_417695054 小时前
C++中的代理模式高级应用
开发语言·c++·算法