目录
- 题目描述
- 题目解析
- 代码实现+对数器
题目描述
给定一个数组arr,代表每个人的能力值。再给定一个非负数k,如果两个人能力差值正好为k,那么可以凑在一起比赛一局比赛只有两个人,返回最多可以同时有多少场比赛
比如: [3,1,5,7],最多同时有2场比赛[3,1];[5,7]
题目解析
先将数组排序,用窗口。
举个例子:
(1)刚开始,L和R均在1位置
(2)L和R能不能比赛?不能,因为它们是一个人,那么R后移
- 必须要区分是不是同一个人,因为k有可能为0
(3)L和R能不能比赛?看两者差值 = arr[R] - arr[L]
- 差值 < K,就让R动(差值要变大)
- 差值 = K,能比赛
- 差值 > K,就让L动(差值要变小)
这里差值 = 0,不能比赛,R移动一位
(3)L和R能不能比赛?看两者差值 = arr[R] - arr[L]
- 差值 = 2,能比赛
那么ans++,然标记3已经用过了,然后移动L和R
因为2,3已经用过了,所以L++,直到第一个没有用过的位置
(4)L和R能不能比赛?不能,因为它们是一个人,那么R后移
(5)L和R能不能比赛?能
(6)R已经超出范围,所以结束
代码实现+对数器
public class MaxPairNumber {
// 暴力解
public static int maxPairNum1(int[] arr, int k) {
if (k < 0) {
return -1;
}
return process1(arr, 0, k);
}
public static int process1(int[] arr, int index, int k) {
int ans = 0;
if (index == arr.length) {
for (int i = 1; i < arr.length; i += 2) {
if (arr[i] - arr[i - 1] == k) {
ans++;
}
}
} else {
for (int r = index; r < arr.length; r++) {
swap(arr, index, r);
ans = Math.max(ans, process1(arr, index + 1, k));
swap(arr, index, r);
}
}
return ans;
}
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
// 时间复杂度O(N*logN)
public static int maxPairNum2(int[] arr, int k) {
if (k < 0 || arr == null || arr.length < 2) {
return 0;
}
Arrays.sort(arr);
int ans = 0;
int N = arr.length;
int L = 0;
int R = 0;
boolean[] usedR = new boolean[N];
while (L < N && R < N) {
if (usedR[L]) { //L跳过已经用过的位置
L++;
} else if (L == R) { // 窗口同一个人时,R++扩大窗口
R++;
} else { // 不止一个数,而且都没用过!
int distance = arr[R] - arr[L];
if (distance == k) {
ans++;
usedR[R++] = true;
L++;
} else if (distance < k) {
R++;
} else {
L++;
}
}
}
return ans;
}
// 为了测试
public static int[] randomArray(int len, int value) {
int[] arr = new int[len];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * value);
}
return arr;
}
// 为了测试
public static void printArray(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
// 为了测试
public static int[] copyArray(int[] arr) {
int[] ans = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
ans[i] = arr[i];
}
return ans;
}
public static void main(String[] args) {
int maxLen = 10;
int maxValue = 20;
int maxK = 5;
int testTime = 1000;
System.out.println("功能测试开始");
for (int i = 0; i < testTime; i++) {
int N = (int) (Math.random() * (maxLen + 1));
int[] arr = randomArray(N, maxValue);
int[] arr1 = copyArray(arr);
int[] arr2 = copyArray(arr);
int k = (int) (Math.random() * (maxK + 1));
int ans1 = maxPairNum1(arr1, k);
int ans2 = maxPairNum2(arr2, k);
if (ans1 != ans2) {
System.out.println("Oops!");
printArray(arr);
System.out.println(k);
System.out.println(ans1);
System.out.println(ans2);
break;
}
}
System.out.println("功能测试结束");
}
}