题目:在一个数组中除了一个数字只出现一次之外,其他数字都出现了三次。请
找出那个只出现一次的数字。
这道题中数字出现了三次,无法像数组中只出现一次的两个数字一样通过利用异或位运算进行消除相同个数字。
但是仍然可以沿用位运算的思路。
将所有数字的二进制表示的对应位都加起来,如果某一位能被三整除,那么只出现一次的数字在该位为0;反之,为1。
一个int型有32位,每一位不是0就是1。对于三个相同的数,统计每一位出现的频率,那么每一位的频率的和一定能被3整除,
也就是说频率和不是3就是0。如果有多组三个相同的数,统计的结果也是类似:频率和不是0就是3的倍数。
现在其中混进了一个只出现一次的数,没关系也统计到频率和中。如果第n位的频率和还是3的倍数,说明只出现一次的这个数第n位是0;
如果不能被3整除了,说明只出现一次的这个数第n位是1。由此可以确定这个只出现一次的数的二进制表示,进而求出该数据。
private int findNumberAppearing(int[] numbers) {
if(numbers==null||numbers.length<=0){
throw new RuntimeException();
}
int a[]=new int[32];
for(int i=0;i< numbers.length;i++){
int bit=1;
for(int j=31;j>=0;j--
){
if((numbers[i]&bit)!=0){
a[j]++;
}
bit=bit<<1;
}
}//0000003413
int result=0;
for(int i=0;i<32;i++){
result=(result<<1)+(a[i]%3);
}
//System.out.println(result);
return result;
}