完成旅途的最少时间

标签: 数组 二分查找

难度: Medium

给你一个数组 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

Submission

运行时间: 577 ms

内存: 29.1 MB

class Solution:
    def minimumTime(self, time: List[int], totalTrips: int) -> int:
        n = len(time)

        left, right = 1, min(time) * totalTrips
        while left <= right:
            mid = left + (right - left) // 2
            s = sum([mid // t for t in time])
            if s < totalTrips:
                left = mid + 1
            else:
                right = mid - 1

        return left

Explain

这道题的核心思路是使用二分查找来确定最少时间完成所有旅途。首先确定搜索的时间范围:最小时间left设为1(最快可能的时间),最大时间right设为min(time) * totalTrips(假设所有旅途都由最快的公交车完成)。在这个搜索范围内,我们计算中间时间点mid,然后计算所有公交车在mid时间内可以完成的旅途总数s。如果s小于totalTrips,意味着mid太小,需要增加时间,因此调整left为mid + 1;如果s大于等于totalTrips,说明可能有解或者可以有更小的解,调整right为mid - 1。当left超过right时,left就是最少需要的时间。

时间复杂度: O(n log(min(time) * totalTrips))

空间复杂度: O(1)

class Solution:
    def minimumTime(self, time: List[int], totalTrips: int) -> int:
        n = len(time)

        # 初始化二分查找的左右边界
        left, right = 1, min(time) * totalTrips
        while left <= right:
            mid = left + (right - left) // 2
            # 计算在mid时间内,所有公交车可以完成的旅途总数
            s = sum([mid // t for t in time])
            if s < totalTrips:
                # 如果完成的旅途数不足,增加时间
                left = mid + 1
            else:
                # 如果完成的旅途数足够或者有余,尝试减少时间
                right = mid - 1

        # 当left > right时,left即为所求最小时间
        return left

Explore

二分查找是解决这个问题的有效方法,因为我们寻找的是满足特定条件(即在给定时间内完成所有旅途)的最小时间。这个时间值从理论上是有序的,即如果某个时间点可以完成所有旅途,那么任何比这个时间点长的时间也都可以;反之,比这个时间点短的时间则不能完成所有旅途。这种有序性质使得二分查找成为寻找最优解的理想选择,因为二分查找能够有效地缩小搜索范围,从而快速地找到满足条件的最小时间。此外,考虑到时间范围可能很大,直接遍历每一个可能的时间点会非常耗时,而二分查找的时间复杂度为O(log n),可以大幅提高效率。