力扣每日一题:5764.准时到达的列车最小时速 Python二分

2021-05-23  本文已影响0人  清风Python

5764.准时到达的列车最小时速

难度:中等

题目:

给你一个浮点数 hour ,表示你到达办公室可用的总通勤时间。要到达办公室,你必须按给定次序乘坐 n 趟列车。另给你一个长度为 n 的整数数组 dist ,其中 dist[i] 表示第 i 趟列车的行驶距离(单位是千米)。

每趟列车均只能在整点发车,所以你可能需要在两趟列车之间等待一段时间。

例如,第 1 趟列车需要 1.5 小时,那你必须再等待 0.5 小时,搭乘在第 2 小时发车的第 2 趟列车。
返回能满足你准时到达办公室所要求全部列车的 最小正整数 时速(单位:千米每小时),如果无法准时到达,则返回 -1 。

生成的测试用例保证答案不超过 107 ,且 hour 的 小数点后最多存在两位数字 。

提示:

示例:

示例 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,不用想就是二分,否则肯定超时!除了二分查找的时间优化,解题过程中有哪些优化点呢?

几点优化

  1. 客车每个整点发车

    由于每趟列车乘坐的长度不同,需要我们对速度除以距离后取整。python整数相除取整公式一定要记住:
    被除数 + 除数 - 1 // 除数,只要整数多1,就可以保证向上取整了。

  2. 至少需要的小时数

    由于列车整点出发,所以速度哪怕无穷大,前n-1车座列车最少也需要n-1个小时,
    最后一次列车可以忽略到无穷小。那么hour 如何小于 len(dist) -1 则肯定无法抵达。

  3. 二分的最大值是多少?

    二分查找需要设置最小值和最大值,然后进行二分操作,这道题的最大值该如何取,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

欢迎关注我的公众号: 清风Python,带你每日学习Python算法刷题的同时,了解更多python小知识。

我的个人博客:https://qingfengpython.cn

力扣解题合集:https://github.com/BreezePython/AlgorithmMarkdown

上一篇下一篇

猜你喜欢

热点阅读