思路:将所有的数字都用二进制表示,对于出现三次的数字,各个 二进制位 出现的次数都是 3 的倍数。
因此,统计所有数字的各二进制位中 1 的出现次数,并对 3 求余,结果则为只出现一次的数字。
class Solution {
public static int singleNumber2(int[] nums) {
int[] bitArr = new int[32];
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < 32; j++) {
bitArr[j] += nums[i] & 1; // 更新bit数组的第 j 位
nums[i] >>>= 1; // 第 j 位 --> 第 j + 1 位
}
}
int res = 0, m = 3;
for (int i = 0; i < 32; i++) {
res <<= 1; // 左移一位
res |= bitArr[31 - i] % m; // 恢复第 i 位的值到 res res += bitArr[31 - i] % m;也可以
}
return res;
}
public static void main(String[] args) {
int[] a = {3, 5, 3, 3};
System.out.println(singleNumber(a));
}
}
另一种思路:排序后,每次比较三个数字,如果不相等则说明找到了。如[1,1,1,2,2,2,3,3,3,4,4,4,5]
class Solution {
public static int singleNumber(int[] nums) {
Arrays.sort(nums);
// 每三个数检查一次
for (int i = 0; i < nums.length - 2; i+=3) {
if (nums[i] != nums[i + 2]){
return nums[i];
}
}
return nums[nums.length - 1];
}
}