leetcode每日一题day22(24.10.2)——准时到达的列车最小时速


**思路:**这种在有约束条件情况下,求最值或最符合要求的情况,首先是很容易想到,从时速为1开始往后找找到满足条件就输出,但这无疑工程量很大,每种可能的速度都要对列车数组进行遍历,

时间复杂度为CN

复制代码
(C为可能的所有速度,在最不好运的情况下,C是有可能远大于N的,本题就是,C最大为10^9 约为N的二次方倍,此时换算成N约为N^3)

优化 :对于一个可能的速度V 如果V 不能满足要求则比V 小的速度都不用再考虑,V 满足要求比V大的速度也必定满足,由此便可引入二分查找。

得到如下代码

cpp 复制代码
class Solution {
public:
    int up_div(int a, int b) { return a / b + (a % b == 0 ? 0 : 1); }
    int minSpeedOnTime(vector<int>& dist, double hour) {
        if (dist.size() - 1 >= hour) {
            return -1;
        }
        int max_v = 1e7, min_v = 1, mid_v, size = dist.size();
        double cut_time = 0;
        while (min_v < max_v) {
            cut_time = 0;
            mid_v = (long)(max_v + min_v) >> 1;
            for (int i = 0; i < size - 1; i++) {
                cut_time += up_div(dist[i], mid_v);
            }
            cut_time += (double)dist[size - 1] / mid_v;
            if (cut_time <= hour) {
                cout<<max_v<<"  ";
                max_v = mid_v;
            } else {
                min_v = mid_v + 1;
            }
        }
        return min_v;
    }
};

此时使用的速度范围为1到1e7 ,其中1e7有题目给出的数据范围得到,(最大的dist为1e7,最小的小数为0.01),由于double进行取整时有精度丢失问题,可以使用round(double) 进行向上取整。

此时时间复杂度为:log2(C)N

复制代码
前者有N^2优化到最差情况也只有30左右,优化巨大

后续则是对速度区间的优化,代码如下(优化不大)

cpp 复制代码
class Solution {
public:
    int up_div(int a, int b) { return a / b + (a % b == 0 ? 0 : 1); }
    int minSpeedOnTime(vector<int>& dist, double hour) {
        // 剪枝
        if (dist.size() - 1 >= hour) {
            return -1;
        }
        int max_v = 0, min_v = 1, mid_v, size = dist.size();
        double cut_time = 0;

        // 优化查找区间阶段
        for (int i : dist) {
            // 当最长的路程,都只需要一个小时即可,那么每汤列车都是花费一个小时,此为最少时间情况下,速度尽可能慢的情况.
            max_v = max(i, max_v);
        }
        int temp = (long)round((hour * 100))% 100;
        if (temp)
            max_v = up_div(max_v * 100, temp );

        // 二分查找阶段
        while (min_v < max_v) {
            cut_time = 0;
            mid_v = (long)(max_v + min_v) >> 1;
            for (int i = 0; i < size - 1; i++) {
                cut_time += up_div(dist[i], mid_v);
            }
            cut_time += (double)dist[size - 1] / mid_v;
            if (cut_time <= hour) {
                max_v = mid_v;
            } else {
                min_v = mid_v + 1;
            }
        }
        return min_v;
    }
};
相关推荐
py有趣19 小时前
LeetCode学习之0矩阵
学习·leetcode·矩阵
sulikey19 小时前
Qt 入门简洁笔记:信号与槽
前端·c++·笔记·qt·前端框架·1024程序员节·qt框架
鸽鸽程序猿19 小时前
【算法】【动态规划】斐波那契数模型
算法·动态规划·1024程序员节
沐怡旸19 小时前
【穿越Effective C++】条款5:了解C++默默编写并调用哪些函数——编译器自动生成的秘密
c++
Samuel-Gyx20 小时前
数据结构--顺序表与链表
数据结构·算法·链表·1024程序员节
小年糕是糕手20 小时前
【数据结构】队列“0”基础知识讲解 + 实战演练
c语言·开发语言·数据结构·c++·学习·算法
无限进步_20 小时前
【C语言】函数指针数组:从条件分支到转移表的优雅进化
c语言·开发语言·数据结构·后端·算法·visual studio
Q741_14720 小时前
C++ 分治 快速选择算法 堆排序 TopK问题 力扣 215. 数组中的第K个最大元素 题解 每日一题
c++·算法·leetcode·分治·1024程序员节·topk问题·快速选择算法
文火冰糖的硅基工坊20 小时前
[人工智能-大模型-57]:模型层技术 - 软件开发的不同层面(如底层系统、中间件、应用层等),算法的类型、设计目标和实现方式存在显著差异。
人工智能·算法·中间件
鱼儿也有烦恼20 小时前
快速学完 LeetCode top 1~50 [特殊字符]
java·算法·leetcode·1024程序员节