同时运行 N 台电脑的最长时间
难度:
标签:
题目描述
你有 n
台电脑。给你整数 n
和一个下标从 0 开始的整数数组 batteries
,其中第 i
个电池可以让一台电脑 运行 batteries[i]
分钟。你想使用这些电池让 全部 n
台电脑 同时 运行。
一开始,你可以给每台电脑连接 至多一个电池 。然后在任意整数时刻,你都可以将一台电脑与它的电池断开连接,并连接另一个电池,你可以进行这个操作 任意次 。新连接的电池可以是一个全新的电池,也可以是别的电脑用过的电池。断开连接和连接新的电池不会花费任何时间。
注意,你不能给电池充电。
请你返回你可以让 n
台电脑同时运行的 最长 分钟数。
示例 1:
输入:n = 2, batteries = [3,3,3] 输出:4 解释: 一开始,将第一台电脑与电池 0 连接,第二台电脑与电池 1 连接。 2 分钟后,将第二台电脑与电池 1 断开连接,并连接电池 2 。注意,电池 0 还可以供电 1 分钟。 在第 3 分钟结尾,你需要将第一台电脑与电池 0 断开连接,然后连接电池 1 。 在第 4 分钟结尾,电池 1 也被耗尽,第一台电脑无法继续运行。 我们最多能同时让两台电脑同时运行 4 分钟,所以我们返回 4 。
示例 2:
输入:n = 2, batteries = [1,1,1,1] 输出:2 解释: 一开始,将第一台电脑与电池 0 连接,第二台电脑与电池 2 连接。 一分钟后,电池 0 和电池 2 同时耗尽,所以你需要将它们断开连接,并将电池 1 和第一台电脑连接,电池 3 和第二台电脑连接。 1 分钟后,电池 1 和电池 3 也耗尽了,所以两台电脑都无法继续运行。 我们最多能让两台电脑同时运行 2 分钟,所以我们返回 2 。
提示:
1 <= n <= batteries.length <= 105
1 <= batteries[i] <= 109
代码结果
运行时间: 100 ms, 内存: 29.4 MB
/* 思路:与普通Java解法相同,使用Java Stream优化部分逻辑。使用Stream计算电池总容量和判断是否能够支持每台电脑运行t时间。*/
import java.util.Arrays;
public class Solution {
public long maxRunTime(int n, int[] batteries) {
long totalCapacity = Arrays.stream(batteries).asLongStream().sum();
long left = 0, right = totalCapacity / n;
while (left < right) {
long mid = right - (right - left) / 2;
if (canRun(batteries, n, mid)) {
left = mid;
} else {
right = mid - 1;
}
}
return left;
}
private boolean canRun(int[] batteries, int n, long time) {
return Arrays.stream(batteries).asLongStream().map(b -> Math.min(b, time)).sum() >= n * time;
}
}
解释
方法:
此题解采用贪心的方法来分配电池资源,确保所有电脑尽可能长时间运行。首先,将电池数组从大到小排序,以优先使用容量大的电池。在遍历处理过程中,计算当前所有电池的总能量s,并尝试均匀分配到n台电脑上。如果当前最大的电池容量x小于或等于平均每台电脑分到的电量s/n,则此时的s/n就是结果,因为这意味着即使最大电池只能支持到s/n分钟,其他电池的容量也足以支持到这个时间。如果不是,则将这个电池的容量从总能量中减去,并减少电脑的数量,继续尝试下一个电池。
时间复杂度:
O(m log m)
空间复杂度:
O(1)
代码细节讲解
🦆
在题解中提到通过排序和逐个检查电池的方法,这种方法在面对特别大的输入数组时效率如何?是否存在更优的解决方案?
▷🦆
题解中的算法依赖于排序电池数组,这里用的是什么排序算法?如何选择最合适的排序算法来优化性能?
▷🦆
在减少电池总容量和电脑数量的步骤中,如何保证每次减少的电池是最合适的?是否有可能出现减少了容量较小的电池导致结果不准确的情况?
▷