【LeetCode - 每日一题】2594. 修车的最少时间(23.09.07)

2594. 修车的最少时间

题意

  • 给定每个师傅修车的时间和需要修的车辆总数,计算修理所有汽车需要的最少时间。
  • 师傅可以同时修车。

解法 二分

看到题目没有任何头绪,直接查看题解。

至于为什么用二分做呢,讨论区有个友友这么说到:

对于修理时间 t t t 来说:

  • 若 t t t 时间内可以修理完所有车,则大于等于 t t t 时间都可以修理完车;
  • 若 t t t时间内不能修理完所有车,则小于等于 t t t 时间也不能修理完车;

存在单调性。因此,假设最少需要 t i m e time time 时间,那么我们要找的就是第一个大于等于 t i m e time time 的时间 t t t 。

所以可以直接套板子:

cpp 复制代码
class Solution {
public:
    long long repairCars(vector<int>& ranks, int cars) {
        long long maxTime = (long long)*max_element(ranks.begin(), ranks.end()) * cars * cars;

        long long left = 0, right = maxTime, middle;
        
        long long maxCar = 0;
        while(left < right)
        {
            long long middle = (left +right) / 2;
            maxCar = 0;
            for(auto rank :ranks)
            {
                maxCar += sqrt(middle / rank);  
            }
            // cout << left << " " << right << " " << middle << " " << maxCar << endl;
            
            if(maxCar < cars)
            {
                left = middle + 1;
            }
            else if(maxCar >= cars)
            {

                right = middle;
            }
        }
        return left;
    }
};

另一种写法:

cpp 复制代码
class Solution {
public:
    long long repairCars(vector<int>& ranks, int cars) {
        long long maxTime = (long long)*max_element(ranks.begin(), ranks.end()) * cars * cars;

        long long left = 0, right = maxTime, middle;
        
        long long maxCar = 0;
        while(left <= right)
        {
            long long middle = (left +right) / 2;
            maxCar = 0;
            for(auto rank :ranks)
            {
                maxCar += sqrt(middle / rank);  
            }
            // cout << left << " " << right << " " << middle << " " << maxCar << endl;
            
            if(maxCar < cars)
            {
                left = middle + 1;
            }
            else if(maxCar > cars)
            {

                right = middle - 1;
            }
            else if(maxCar == cars)
            {
                right = middle - 1;
            }
        }
        return left;
    }
};

板子:

cpp 复制代码
int lower_bound(int a[],int left,int right,int x) 	//第一个小于等于x的数的位置 
{
	int mid;
	while(left<right)
	{
		mid=(left+right)/2;
		if(a[mid]>=x)
			right=mid;
		else
			left=mid+1;
	}
	return left;
}

int lower_bound(int a[],int left,int right,int x) 	//第一个小于等于x的数的位置 
{
	int mid;
	while(left<=right)
	{
		mid=(left+right)/2;
		if(a[mid]>=x)
			right=mid-1;
		else
			left=mid+1;
	}
	return left;
}

复杂度

时间复杂度:O( r a n k s . s i z e ( ) ∗ ( log ⁡ m a x ( r a n k ∗ c a r s ∗ c a r s ) ) ranks.size() * (\log max(rank*cars*cars)) ranks.size()∗(logmax(rank∗cars∗cars)) ),每一次二分都要遍历 ranks 数组计算可修理最大车辆数。

空间复杂度:O(1),常数个变量。


相关推荐
feiyangqingyun几秒前
Qt/C++编写GB28181服务端工具/绿色版开箱即用/对标wvp-gb28181/实时画面预览/录像回放下载
c++·qt·gb28181·监控系统开发
三体世界13 分钟前
Linux --TCP协议实现简单的网络通信(中英翻译)
linux·c语言·开发语言·网络·c++·windows·tcp/ip
csdn_aspnet36 分钟前
C++ 检查一条线是否与圆接触或相交(Check if a line touches or intersects a circle)
c++·算法
Musennn1 小时前
leetcode93.复原IP地址:回溯算法中段控制与前导零处理的深度解析
java·数据结构·算法·leetcode
爱coding的橙子1 小时前
每日算法刷题计划Day20 6.2:leetcode二分答案3道题,用时1h20min
算法·leetcode·职场和发展
clock的时钟2 小时前
c++面向对象第4天---拷贝构造函数与深复制
开发语言·c++
CodeWithMe2 小时前
【C/C++】面试常考题目
c语言·c++·面试
子豪-中国机器人2 小时前
2025年5月18日蓝桥stema省选拔赛编程题答案解析
c++·算法·数学建模
岁忧2 小时前
LeetCode 高频 SQL 50 题(基础版) 之 【高级查询和连接】· 上
数据库·sql·leetcode
秋风&萧瑟3 小时前
【C++】类的构造函数
开发语言·c++