Leetcode 2594.修车的最少时间

目录

2594. 修车的最少时间 - (LeetCode)

思路解析

AC代码


2594. 修车的最少时间 - (LeetCode)

题目描述

给你一个整数数组 ranks ,表示一些机械工的 能力值 。ranksi 是第 i 位机械工的能力值。能力值为 r 的机械工可以在 r * n2 分钟内修好 n 辆车。

同时给你一个整数 cars ,表示总共需要修理的汽车数目。

请你返回修理所有汽车 最少 需要多少时间。

注意:所有机械工可以同时修理汽车。

样例

输入:ranks = [4,2,3,1], cars = 10
输出:16
解释:
- 第一位机械工修 2 辆车,需要 4 * 2 * 2 = 16 分钟。
- 第二位机械工修 2 辆车,需要 2 * 2 * 2 = 8 分钟。
- 第三位机械工修 2 辆车,需要 3 * 2 * 2 = 12 分钟。
- 第四位机械工修 4 辆车,需要 1 * 4 * 4 = 16 分钟。
16 分钟是修理完所有车需要的最少时间。

思路解析

    首先,我们观察到的一个任务的完成时间是所有修车厂完成时间的最大值。使用数学语言表达就是 time = max{r_i * n_i ^ 2}。而这道问题就是让我们求取 min{time}。所以这是一道最小化最大值的题型。所以,我们可以使用二分答案 -- 二分查找

    明确算法之后,我们来判定二分什么?二分的核心在于求值转变为判定。同时,此时二分的区域是答案 -- 值域,所以的判定的位置在与其他位置。关注到定义域为 n 的范围, 表达式 time_i = r_i * n_i ^ 2,且 ∑n_i = cars。所以,我们可以知道 n_i = sqrt(time_i / r_i)。显然 n_i 与 time_i 是正相关关系所以当 ∑n_i >= cars 时,必有 time_i >= time。其中 time 是所求的答案。

AC代码

class Solution {
    bool check(vector<int>& ranks, long long times, long long cars) {
        long long tot = 0;
        for (int i = 0; i < ranks.size(); ++i) {
            tot += (long long) (sqrt(times / ranks[i])); // 需要向下取整,因为车辆数需要是整数
        }
        return tot >= cars;
    }
public:
    long long repairCars(vector<int>& ranks, int cars) {
        long long begin = 1,  end = 10e15; // 查询足够大的范围即可
        while (begin < end) {
            long long mid = begin + (end - begin >> 1);
            if (check(ranks, mid, cars)) {
                end = mid;
            } // time_i >= time
            else {
                begin = mid + 1;
            } // time_i < time
        } // 二分答案 -- lower_bound为模板
        return begin; // time_i == time
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值