5764.准时到达的列车最小时速
难度:中等
题目:
给你一个浮点数 hour ,表示你到达办公室可用的总通勤时间。要到达办公室,你必须按给定次序乘坐 n 趟列车。另给你一个长度为 n 的整数数组 dist ,其中 dist[i] 表示第 i 趟列车的行驶距离(单位是千米)。
每趟列车均只能在整点发车,所以你可能需要在两趟列车之间等待一段时间。
例如,第 1 趟列车需要 1.5 小时,那你必须再等待 0.5 小时,搭乘在第 2 小时发车的第 2 趟列车。
返回能满足你准时到达办公室所要求全部列车的 最小正整数 时速(单位:千米每小时),如果无法准时到达,则返回 -1 。
生成的测试用例保证答案不超过 107 ,且 hour 的 小数点后最多存在两位数字 。
提示:
- n == dist.length
- 1 <= n <= 10**5
- 1 <= dist[i] <= 10 ** 5
- 1 <= hour <= 10 ** 9
- hours 中,小数点后最多存在两位数字
示例:
示例 1: 输入:dist = [1,3,2], hour = 6 输出:1 解释:速度为 1 时: - 第 1 趟列车运行需要 1/1 = 1 小时。 - 由于是在整数时间到达,可以立即换乘在第 1 小时发车的列车。第 2 趟列车运行需要 3/1 = 3 小时。 - 由于是在整数时间到达,可以立即换乘在第 4 小时发车的列车。第 3 趟列车运行需要 2/1 = 2 小时。 - 你将会恰好在第 6 小时到达。 示例 2: 输入:dist = [1,3,2], hour = 2.7 输出:3 解释:速度为 3 时: - 第 1 趟列车运行需要 1/3 = 0.33333 小时。 - 由于不是在整数时间到达,故需要等待至第 1 小时才能搭乘列车。第 2 趟列车运行需要 3/3 = 1 小时。 - 由于是在整数时间到达,可以立即换乘在第 2 小时发车的列车。第 3 趟列车运行需要 2/3 = 0.66667 小时。 - 你将会在第 2.66667 小时到达。 示例 3: 输入:dist = [1,3,2], hour = 1.9 输出:-1 解释:不可能准时到达,因为第 3 趟列车最早是在第 2 小时发车。
分析
这道题简直太符合每天卡点签到的我了,从7点55出门开始,一直优化到现在每天8点25风一般的卡点签到,哈哈。
这道题看到10**7,不用想就是二分,否则肯定超时!除了二分查找的时间优化,解题过程中有哪些优化点呢?
几点优化
- 客车每个整点发车
由于每趟列车乘坐的长度不同,需要我们对速度除以距离后取整。python整数相除取整公式一定要记住:被除数 + 除数 - 1 // 除数
,只要整数多1,就可以保证向上取整了。 - 至少需要的小时数
由于列车整点出发,所以速度哪怕无穷大,前n-1车座列车最少也需要n-1个小时,
最后一次列车可以忽略到无穷小。那么hour 如何小于 len(dist) -1 则肯定无法抵达。 - 二分的最大值是多少?
二分查找需要设置最小值和最大值,然后进行二分操作,这道题的最大值该如何取,10**9吗?那你要多算多少次啊!
由于题目说了,hour小数最多存在两位,也就是最快0.01,那么右端点只需设置max(dist) * 100
就能满足题意。
这样会比 10 ** 9时间复杂度降低很多!
最后需要注意一点,hour的小数是怎么来的?因为前n-1次列车都是整点出发,所以小数是通过最后一趟列车来的!
下车后就认为到达终点了(地铁里打卡的骚操作?)。所以二分只循环计算前n-1,最后一次直接除保留小数。
理解了上面这些内容,这道题就变的很简单了,但Python的效率注定再怎么优化,耗时也渣的不行,尤其在大的数据量上更为明显。
来看看解题吧。
解题:
class Solution: def minSpeedOnTime(self, dist, hour): # 如果时间小于dist -1返回 -1 if hour < len(dist) - 1: return -1 # 设置二分查找边界 left,right = 1, max(dist) * 100 while left < right: cost, mid = 0, (left + right) // 2 for i in dist[:-1]: cost += (i + mid - 1) // mid # 如果cost已经大于hour,直接left移位,重新计算 if cost > hour: left = mid + 1 continue # 单独计算最后一次的耗时 cost += dist[-1] / mid if cost > hour: left = mid + 1 else: right = mid return -1 if left == 10 ** 9 else left