题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。

      例如输入数组{2,4,3,6,3,2,5,5},因为只有4,6这两个数字只出现一次,其他数字都出现了两次,所以输出4和6。

       两个相同的数字异或结果为0,把原数组分成两个子数组,使得每个子数组包含一个只出现一次的数字,而其他数字都成对出现两次。将原始数组的所有数字进行异或运算,得到异或结果。找出这个异或结果数字第一次出现1的位的位置,记为第n位。然后以第n位是不是1为标准把原数组中的数字分为两个子数组。两个子数组在进行异或操作就得到结果了。

代码实现:

public class Solution{
     public static void findNumsAppearOnce(int[] data,int[] result){
         if(data==null||data.length<2){
              return;
         }
         int or=0;
         for(int i=0;i<data.length;i++){
              or^=data[i];
         }
         int index=findFirstBitIs1(or);
         for(int i=0;i<data.length;i++){
              if(isBit1(data[i],index)){
                   result[0]^=data[i];
              }else{
                  result[1]^=data[i];
              }
         }
     }

     //找出num从后数第几位是1
     public static int findFirstBitIs1(int num){
         int index=0;
         while((num&1)==0){
              num=num>>1;
              index++;
         }
         return index;
     }

     //移位之后判断是奇数还是偶数,这样就可以分为两个子数组
     public static boolean isBit1(int num,int index){
          num=num>>index;
          return (num&1)==1?true:false;
     }

     public static void main(String[] args){
         int[] array={2,4,3,6,3,2,5,5};
         int[] number=new int[2];
         findNumsAppearOnce(array,number);
         for(int i:number){
            System.out.println(i);
         }
     }
}

 

 posted on 2018-11-25 15:38  会飞的金鱼  阅读(102)  评论(0)    收藏  举报