题目
2141. 同时运行 N 台电脑的最长时间 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/maximum-running-time-of-n-computers/
解题思路
总的来说,功力还很不足。
方法一
我拿到题目第一想法就是模拟这个过程,就是下面代码的maxRunTime1方法,每次都从最大的n个里面取数字,取完之后做一个重排序。从debug界面看到,这个效率太低了,虽然能得到结果,但给leetcode必然是超时的。
方法二
假如认为排序过程太长了,那就把排序过程取消掉, 采用优先队列的方式。每次取n+1个位置,消去n个位置,放回去n+1,用优先队列帮我们排序。
用优先队列搞起来,也是十分耗时的,必然也是无法通过。
方法三
参考了一个大佬的方法
(1)对数组排序、求和
(2)从大到小进行一次遍历,当发现你的电池容量已经超过了平均值,那这个电池就只能为一台电脑充电到永远。让后将该电池直接移除,需要充电的电脑也不用管了。
解题代码
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
public class Solution2141 {
public static void main(String[] args) {
Solution2141 solution5938 = new Solution2141();
System.out.println(solution5938.maxRunTime(2, new int[]{
49, 94, 36, 96, 36, 64, 21, 17, 30, 62, 50, 1, 72, 17, 32, 51, 80}));
}
public long maxRunTime1(int n, int[] batteries) {
long res = 0;
int l = batteries.length;
int last = l - 1;
int start = l - n;
int beforeStart = l - n - 1;
while (true) {
Arrays.sort(batteries);
if (batteries[start] <= 0) {
return res;
}
int div;
if (batteries[beforeStart] == 0) {
div = batteries[start];
} else {
div = batteries[start] - batteries[beforeStart] + 1;
}
for (int i = start; i <= last; i++) {
batteries[i] = batteries[i] - div;
}
res += div;
}
}
public long maxRunTime2(int n, int[] batteries) {
long res = 0;
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(Comparator.reverseOrder());
for (int battery : batteries) {
priorityQueue.add(battery);
}
while (true) {
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i <= n; i++) {
list.add(priorityQueue.poll());
}
int beforeStart = list.get(list.size() - 1);
int start = list.get(list.size() - 2);
if (start <= 0) {
return res;
}
int div;
if (beforeStart == 0) {
div = start;
} else {
div = start - beforeStart + 1;
}
res += div;
for (int i = 0; i < n; i++) {
priorityQueue.add(list.get(i) - div);
}
priorityQueue.add(beforeStart);
}
}
public long maxRunTime(int n, int[] batteries){
Arrays.sort(batteries);
System.out.println(Arrays.toString(batteries));
long sum = sumArrary(batteries);
for (int i=batteries.length-1;i>=0;i--){
if (batteries[i]>sum/n) {
n--;
sum = sum-batteries[i];
}else {
return sum/n;
}
}
return sum/n;
}
private static long sumArrary(int[] arr) {
//实现一个方法 sum, 以数组为参数, 求数组所有元素之和.
long sum = 0;
for (int value : arr) {
sum += value;
}
return sum;
}
}