题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写出程序找出这两个只出现一次的数字。要求时间复杂度为o(n),空间复杂度是o(1)。
这两个题目都在强调一个(或两个)数字只出现一次,其他的出现两次。这有什么意义呢?我们想到异或运算的一个性质:任何一个数字异或它自己都等于0。也就是说,如果我们从头到尾依次疑惑数组中的每一个数字,那么最终的结果刚好是那个只出现一次的数字,因为那些成对出现两次的数字全部在异或中抵消了。
想明白怎么解决这个简单问题之后,我们再回到原始的问题,看看能不能运用相同的思路。我们试着把原数组分成两个子数组,使得每个子数组包含一个只出现一次的数字,而其他数字都成对出现两次。如果能够这样拆分两个数组,我们就可以按照前面的办法分别找出两个只出现一次的数字了。
思路:
1、首先异或本身,找出最终的结果。
2、根据结果找出1的位置。
3、根据数组中相应的位置是否含有1决定异或的数组。
public class oneToCount{ public void getCount(int[] array){ if(array==null || array.length<2) return ; int yihuo=array[0]; for(int i=1;i<array.length;i++){ yihuo ^= array[i]; } int result = getOneBit(yihuo); int num1=0; int num2=0; for(int i=0;i<array.length;i++){ if(isOneBit(array[i],result)!=0) num1 ^= array[i]; else num2 ^= array[i]; } System.out.println(num1); System.out.println(num2); } public int getOneBit(int n){ int count =0; while((n&1)==0){ ++count; n=n>>1; } return count; } public int isOneBit(int n,int m){ n = n>>m; return (n&1); } public static void main(String[] args){ oneToCount o = new oneToCount(); int[] array = {2,4,3,6,3,2,5,5}; o.getCount(array); } }