You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
2.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class_2023_03_3_week;
import java.util.ArrayList;
import java.util.Arrays;
// 来自学员问题
// 真实大厂笔试题
// 给定一个数组arr长度为n
// 再给定一个数字k表示一定要将arr划分成k个集合
// 每个数字只能进一个集合
// 返回每个集合内部的平均值都累加起来最小的值
// 平均值向下取整
// 1 <= n <= 10^5
// 0 <= arr[i] <= 10^5
// 1 <= k <= n
public class Code02_SplitToSubsetMakeMinAverageSum {
// 暴力方法
// 为了验证
public static int minAverageSum1(int[] arr, int k) {
if (arr.length < k) {
return -1;
}
ArrayList<Info> sets = new ArrayList<>();
for (int i = 0; i < k; i++) {
sets.add(new Info(0, 0));
}
return process(arr, 0, k, sets);
}
// 暴力方法
// 为了验证
public static class Info {
public int sum;
public int cnt;
public Info(int s, int c) {
sum = s;
cnt = c;
}
}
// 暴力方法
// 为了验证
public static int process(int[] arr, int i, int k, ArrayList<Info> sets) {
if (i == arr.length) {
int ans = 0;
for (Info set : sets) {
if (set.cnt == 0) {
return Integer.MAX_VALUE;
} else {
ans += set.sum / set.cnt;
}
}
return ans;
} else {
int ans = Integer.MAX_VALUE;
int cur = arr[i];
for (int j = 0; j < k; j++) {
sets.get(j).sum += cur;
sets.get(j).cnt += 1;
ans = Math.min(ans, process(arr, i + 1, k, sets));
sets.get(j).sum -= cur;
sets.get(j).cnt -= 1;
}
return ans;
}
}
// 正式方法
// 时间复杂度O(N * logN)
public static int minAverageSum2(int[] arr, int k) {
if (arr.length < k) {
return -1;
}
Arrays.sort(arr);
int ans = 0;
for (int i = 0; i < k - 1; i++) {
ans += arr[i];
}
int sum = 0;
for (int i = k - 1; i < arr.length; i++) {
sum += arr[i];
}
ans += sum / (arr.length - k + 1);
return ans;
}
// 生成随机数组
// 为了测试
public static int[] randomArray(int n, int v) {
int[] ans = new int[n];
for (int i = 0; i < n; i++) {
ans[i] = (int) (Math.random() * v);
}
return ans;
}
// 随机测试对数器
// 为了测试
public static void main(String[] args) {
int N = 8;
int V = 10000;
int testTimes = 2000;
System.out.println("测试开始");
for (int i = 0; i < testTimes; i++) {
int n = (int) (Math.random() * N) + 1;
int[] arr = randomArray(n, V);
int k = (int) (Math.random() * n) + 1;
int ans1 = minAverageSum1(arr, k);
int ans2 = minAverageSum2(arr, k);
if (ans1 != ans2) {
System.out.println("出错了!");
}
}
System.out.println("测试结束");
}
}