题目
一个数组中,如果其他数出现了M次,有一个数出现了K次,返回这个数,如果没有出现K次,那么返回-1
要求:额外空间复杂度O(1),时间复杂度O(N)
解析
因为有要求时间复杂度和空间复杂度,那么最好的解法仍然是使用位运算,这里使用的位运算比较巧妙
这个题相对于上一题,增加了限制,可能会出现没有出现K次的数,那么就需要考虑边界情况
代码实现
public static int onlyKTimes2(int[] arr, int K, int M) {
int[] t = new int[32];
for (int i = 0; i < arr.length; i++) {
// 计算每个数在32位上的每个位上的值的累加
for (int j = 0; j < 32; j++) {
t[j] += (arr[i] >> j) & 1;
}
}
int ans = 0;
for (int i = 0; i < t.length; i++) {
if(t[i] == 0) {
continue;
}
// 如果该位置上的累加和取余为K,那么说明出现K次的数在该位置上为1
if(t[i] % M == K) {
ans |= (1 << i);
} else {
// 如果余数不等于K,那么说明没有出现K次的数
return -1;
}
}
// 兼容原数组总出现次数为K次,但是数据为0的情况
if(ans == 0) {
int count = 0;
for (int num : arr) {
if(num == 0) {
count++;
}
}
if(count != K) {
return -1;
}
}
return ans;
}