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

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

作者: 清风Python | 来源:发表于2021-05-23 23:30 被阅读0次

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

    几点优化

    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

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/arstsltx.html