数组中只出现一次的数字

题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

思路:1. 如果一组数字中,只有一个数字出现一次,而其他数字都出现两次,要求那个只出现一次的数字时由于数字和他本身异或为0,且数字的异或性质同乘法一样,满足交换率,所以依次异或后,剩余的数值肯定是只出现一次的数值。

   2.根据这个思路,我们将数组分裂成两组,每组中只包含出现一次的数组和出现两次的数字。

   3.在这两组数组中,分别进行异或,每组得到的结果就是相应的出现一次的数字。

难点:1.判断一个数字的二进制中某一位是否为1

   思路:某一位为1,则将该位和1相与,相当于乘法。将1左移i位,与数字相与,若为0,则该位为0,若为1,则该位为1.

   2.怎样求一个数字的二进制中某一位为1的位置。

   思路:将1移i位和该数字相与直到为1,移的位数就是1的位置。

   3.怎样将一个数字的二进制中的某一位清0. 1->0(取反就是或)

   思路:将1移i位和该数字相与。

 

  

public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
        int recursive = 0;
        //异或得到的两个只出现一次的数的异或
        for(int i=0;i<array.length;i++){
            recursive ^= array[i];
        }
        //查询最低位1出现的位置
        int location = 0;
        while((recursive&1)==0){
            recursive >>= 1;
            location++;
        }
        //按照1的位置将数组分成两组,每组中只有一个字出现一次,其余出现两次,异或到最后就是出现一次的值。
        int p=0;
        int q=0;
        for(int i=0;i<array.length;i++){
            if(getBit(array[i],location)){
                p^=array[i];
            }
            else if(!getBit(array[i],location)){
                q^=array[i];
            }
        }
        num1[0] = p;
        num2[0] = q;
        System.out.println(num1[0]+" "+num2[0]);
    }
    //判断一个数值的第i位是否为1
    public boolean getBit(int num,int index){
        if(num == 0) return false;
         return (num&(1<<index))==0;
    }

 

posted @ 2016-09-01 10:46  樱圃  阅读(283)  评论(0编辑  收藏  举报