【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),常数个变量。


相关推荐
Swift社区3 分钟前
LeetCode 402 - 移掉 K 位数字
算法·leetcode·职场和发展
起床气2338 分钟前
C++海战棋开发日记(序)
开发语言·c++
_码力全开_27 分钟前
P1005 [NOIP 2007 提高组] 矩阵取数游戏
java·c语言·c++·python·算法·矩阵·go
墨染点香31 分钟前
LeetCode 刷题【124. 二叉树中的最大路径和、125. 验证回文串】
算法·leetcode·职场和发展
孤廖1 小时前
吃透 C++ 栈和队列:stack/queue/priority_queue 用法 + 模拟 + STL 标准实现对比
java·开发语言·数据结构·c++·人工智能·深度学习·算法
小龙报1 小时前
《算法通关指南---C++编程篇(3)》
开发语言·c++·算法·visualstudio·学习方法·visual studio
Mr_WangAndy2 小时前
C++设计模式_行为型模式_状态模式State
c++·设计模式·状态模式
郝学胜-神的一滴2 小时前
Effective STL 第5条:区间成员函数优先于单元素成员函数
开发语言·c++·程序人生·stl·软件工程
2201_758875442 小时前
LeetCode:19. 删除链表的倒数第 N 个结点
算法·leetcode·链表