package class_2022_02_3_week; import java.util.Arrays; // 来自微软 // 给定一个数组arr,一个正数num,一个正数k // 可以把arr中的某些数字拿出来组成一组,要求该组中的最大值减去最小值<=num // 且该组数字的个数一定要正好等于k // 每个数字只能选择进某一组,不能进多个组 // 返回arr中最多有多少组 public class Code04_MaxTeamNumber { // 对数器方法 public static int maxTeams1(int[] arr, int num, int k) { Arrays.sort(arr); return process1(arr, 0, new int[arr.length], 0, num, k); } public static int process1(int[] arr, int index, int[] path, int size, int num, int k) { if (index == arr.length) { if (size % k != 0) { return 0; } else { for (int start = 0; start < size; start += k) { if (path[start + k - 1] - path[start] > num) { return 0; } } return size / k; } } else { int p1 = process1(arr, index + 1, path, size, num, k); path[size] = arr[index]; int p2 = process1(arr, index + 1, path, size + 1, num, k); return Math.max(p1, p2); } } // 正式方法 // 时间复杂度O(N * logN) public static int maxTeams2(int[] arr, int num, int k) { int n = arr.length; if (k > n) { return 0; } Arrays.sort(arr); int[] dp = new int[n]; dp[k - 1] = arr[k - 1] - arr[0] <= num ? 1 : 0; for (int i = k; i < n; i++) { int p1 = dp[i - 1]; int p2 = (arr[i] - arr[i - k + 1] <= num ? 1 : 0) + dp[i - k]; dp[i] = Math.max(p1, p2); } return dp[n - 1]; } // 为了测试 public static int[] randomArray(int len, int value) { int[] ans = new int[len]; for (int i = 0; i < len; i++) { ans[i] = (int) (Math.random() * value); } return ans; } // 为了测试 public static void main(String[] args) { int n = 18; int v = 50; int testTimes = 20000; System.out.println("测试开始"); for (int i = 0; i < testTimes; i++) { int len = (int) (Math.random() * n) + 1; int[] arr = randomArray(len, v); int num = (int) (Math.random() * v) + 1; int k = (int) (Math.random() * len) + 1; int ans1 = maxTeams1(arr, num, k); int ans2 = maxTeams2(arr, num, k); if (ans1 != ans2) { for (int number : arr) { System.out.print(number + " "); } System.out.println(); System.out.println("num : " + num); System.out.println("k : " + k); System.out.println(ans1); System.out.println(ans2); break; } } System.out.println("测试结束"); } }