publicstaticvoidfindNumsAppearOnce(int[] array,int num1[],int num2[]){if(array == null || array.length <=1){
num1[0]= num2[0]=0;return;}int len = array.length, index =0, sum =0;/**
*思路:
*数组中有两个出现一次的数字,这两个数字32位的二进制位中至少有一位不同,数组全部数字相与,找
*出不同的二进制位
*/for(int i =0; i < len; i++){
sum ^= array[i];}/**
*找出上一步不同的二进制位是32位中的第几位index
*/for(; index <32; index++){if((sum &(1<< index))!=0)break;}/**
*将数组中的数字与index位相与,两个不同的数字与的结果,其中一个的结果不会为0,另一个为0。因
*此能保证分到不同的数组中,其他的数会两两分到同一个数组中。
*/for(int i =0; i < len; i++){if((array[i]&(1<< index))!=0){
num2[0]^= array[i];}else{
num1[0]^= array[i];}}}
/**
* 数组a中只有一个数出现一次,其他数都出现了2次,找出这个数字
* @param a
* @return
*/
publicstaticintfind1From2(int[] a){int len = a.length, res =0;for(int i =0; i < len; i++){
res = res ^ a[i];}return res;}
* 数组a中只有一个数出现一次,其他数字都出现了3次,找出这个数字
* @param a
* @return
*/
/**
*思路:
*定义一个32位的数组bits
*遍历数组a中数字的每一位,如果该位为1,则将bits数组对应位置值加1
*因为只有1位数字res存在1位,遍历bits数组,如果哪一位的值不是3的倍数,则该位在res中一定为1
*最终找到res中所有二进制为1的位置。
*/publicstaticintfind1From3(int[] a){int[] bits =newint[32];int len = a.length;for(int i =0; i < len; i++){for(int j =0; j <32; j++){
bits[j]= bits[j]+((a[i]>>>j)&1);}}int res =0;for(int i =0; i <32; i++){if(bits[i]%3!=0){
res = res |(1<< i);}}return res;}