数组中只出现一次的数字
题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
思路: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; }