找出数组中出现一次的三个数,其他数都出现两次

来源:互联网 发布:天涯明月刀心法数据 编辑:程序博客网 时间:2024/05/16 15:22
package 数组;
/*找出数组中出现一次的三个数,其他数都出现两次
讲解链接:http://zhedahht.blog.163.com/blog/static/25411174201283084246412/
f(x^a)^f(x^b)^f(x^c)结果最后一位为1的位数可以找到第一个出现一次的数
*/
public class Find3numAppearOnce {
public static void main(String[] args) {
int[]a={1,1,2,3,4,5,4};
find(a);
}
public static void find(int[]a){
int len=a.length;
if(a.length<3) return;
int xornum=0;
for(int i=0;i<len;i++){//所有数异或
xornum^=a[i];
}
int flag=0; //找到f(x^a)^f(x^b)^f(x^c)结果最后一位为1的位数
for(int i=0;i<len;i++){
flag^=f(xornum^a[i]);
}
flag=f(flag); //找到第一个出现一次的数
int first=0;
for(int i=0;i<len;i++){
if(f(a[i])==flag)
{ first=a[i];
swap(a,i,len-1);
}
}

//找出剩下的两个出现一次的数
int xor2=0;
for(int i=0;i<len-1;i++){
xor2^=a[i];
}
int flag2=f(xor2);
int second=0,three=0;
for(int i=0;i<len-1;i++){
if(isbit1(a[i],flag2)){
second^=a[i];
}else{
three^=a[i];
}
}
System.out.println(first+","+second+","+three);
}
private static void swap(int[] a, int i, int j) {
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
public static int f(int num){//num的最后一个1是倒数第几位
return num&(-num);
}
private static boolean isbit1(int i, int index){//数i的倒数第index位是不是1

return ((i>>index)&1)==1;
}
}
阅读全文
0 0
原创粉丝点击