修车的最少时间【LC2594】
给你一个整数数组
ranks
,表示一些机械工的 能力值 。ranksi
是第i
位机械工的能力值。能力值为r
的机械工可以在r * n2
分钟内修好n
辆车。同时给你一个整数
cars
,表示总共需要修理的汽车数目。请你返回修理所有汽车 最少 需要多少时间。
**注意:**所有机械工可以同时修理汽车。
-
思路:二分答案
- 二段性:二分最少时间
time
,在以time
为分割点具有「二段性」:- 小于
time
的值,总修车数目 t o t a l total total必然不满足 t o t a l ≥ c a r s total \ge cars total≥cars; - 大于等于
time
的值,总修车数目 t o t a l total total必然满足 t o t a l ≥ c a r s total \ge cars total≥cars。
- 小于
- 因此当修车数目一定时,可以通过二分查找搜索修完所有车的最少时间,二分查找的下限为1,上限为由某一位机械工修完所有车的时间
check
函数:一位修车工在time
时间内,能够修理的数目为 t i m e / r a n k \sqrt {time/rank} time/rank,求出所有修车工在time
时间内能够修理的数目,如果大于等于cars
,那么返回true
- 二段性:二分最少时间
-
实现
class Solution { public long repairCars(int[] ranks, int cars) { long l = 1L; long r = 1L * ranks[0] * cars * cars; while (l <= r){ long mid = l + (r - l) / 2; if (check(ranks, mid, cars)){ r = mid - 1; }else{ l = mid + 1; } } return l; } public boolean check(int[] ranks,long time, int target){ int total = 0; for (int rank : ranks){ total += (int)Math.sqrt(time / rank); if (total >= target){ return true; } } return false; } }
- 复杂度
- 时间复杂度: O ( n l o g m ) O(nlogm) O(nlogm), n n n是数组的长度,m是二分查找的上界。二分查找的时间复杂度是 O ( l o g m ) O(logm) O(logm),每次判断需要的时间复杂度为 O ( n ) O(n) O(n)
- 空间复杂度: O ( 1 ) O(1) O(1)
- 复杂度