一个数组中只有一个数出现了k次,还有其他的数都出现了m次,k < m ,k > 1,找出只出现了k次的那一个数
不能使用hash表和词频统计的方法,而且必须在O(n)的时间复杂度内找到
import java.util.*;
public class Main {
public static int test(int[] arr,int k,int m) {
HashMap<Integer,Integer> map = new HashMap<>();
for (int num : arr) {
if (map.containsKey(num)) {
map.put(num, map.get(num) + 1);
} else {
map.put(num, 1);
}
}
int ans = 0;
for (int num : map.keySet()) {
if (map.get(num) == k) {
ans = num;
break;
}
}
return ans;
}
public static int onlyOne(int[] arr,int k ,int m) {
int[] t = new int[32];
for (int num:arr) {
for (int i = 0;i < 32;i++) {
t[i] += (num >> i ) & 1;
}
}
int ans = 0;
for (int i = 0;i < 32;i++) {
if (t[i] % m != 0) ans |= (1 << i);
}
return ans;
}
// 为了测试
public static int[] randomArray(int maxKinds, int range, int k, int m) {
int ktimeNum = randomNumber(range);
// 真命天子出现的次数
int times = k;
// 2
int numKinds = (int) (Math.random() * maxKinds) + 2;
// k * 1 + (numKinds - 1) * m
int[] arr = new int[times + (numKinds - 1) * m];
int index = 0;
for (; index < times; index++) {
arr[index] = ktimeNum;
}
numKinds--;
HashSet<Integer> set = new HashSet<>();
set.add(ktimeNum);
while (numKinds != 0) {
int curNum = 0;
do {
curNum = randomNumber(range);
} while (set.contains(curNum));
set.add(curNum);
numKinds--;
for (int i = 0; i < m; i++) {
arr[index++] = curNum;
}
}
// arr 填好了
for (int i = 0; i < arr.length; i++) {
// i 位置的数,我想随机和j位置的数做交换
int j = (int) (Math.random() * arr.length);// 0 ~ N-1
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
return arr;
}
// 为了测试
// [-range, +range]
public static int randomNumber(int range) {
return (int) (Math.random() * (range + 1)) - (int) (Math.random() * (range + 1));
}
public static void main(String[] args ) throws Exception {
/*int[] arr = {12,-99,12,12,1,1,1,2,2,2,3,3,3,4,4,4};
int k = 2,m = 3;
System.out.println(onlyOne(arr,k,m));*/
int testTime = 100001, maxlen = 5, range = 30;
int max = 9;
System.out.println("测试开始");
int[] arr = new int[range];
int num1 = 0,num2 = 0;
for (int i = 0; i < testTime; i++) {
int a = (int) Math.random() * max + 1;
int b = (int) Math.random() * max + 1;
int k = Math.min(a, b);
int m = Math.max(a, b);
if (k == m) {
m++;
}
arr = randomArray(maxlen, range, k, m);
num1 = onlyOne(arr, k, m);
num2 = test(arr, k, m);
if (num1 != num2) {
System.out.println("程序出错了");
}
}
for (int num:arr) {
System.out.printf("%d ",num);
}
System.out.println();
System.out.println("测试结束!!!");
System.out.printf("test: %d\n",num1);
System.out.printf("onlytest: %d\n",num2);
// public static int[] RandomArray(int maxlen,int range) {
// return null;
// }
}
}