一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
先考虑另一个问题,一个整型数组里除了一个数字之外,其他的数字都出现了两次,那把所有的数据异或起来,异或的结果就是那一个数字。(因为出现过两次的数字异或起来就抵消了)
对于这个题来说,如果把数字全异或起来,最后异或出来的结果是不同的那两个数的异或,然后随便从异或结果里面找一位1,因为某一位上异或结果是1的话,说明要找两个数,这一位上一个是1,一个是0。那么就可以把原来数组中,这一位是1的分成一组,这一位是0的分成一组。这样就有了两组每一组中会包含一个不同的数和一部分出现两次的数。 然后组内异或就可以了。
c++
class Solution { public: vector<int> FindNumsAppearOnce(vector<int>& array) { vector<int>ans; int ans1 = 0,ans2 = 0; int XORsum = 0; for(int i = 0 ; i < array.size() ; i++) { XORsum ^= array[i]; } int t = 1;//找出异或和中哪一位是1 while((XORsum&t)==0) { t=t<<1; } for(int i = 0 ; i < array.size() ; i++) { if(t&array[i]) { ans1 ^= array[i]; } else{ ans2 ^= array[i]; } } ans.push_back(min(ans1,ans2)); ans.push_back(max(ans1,ans2)); return ans; } };
java
import java.util.*; public class Solution { public int[] FindNumsAppearOnce (int[] array) { int[] ans = new int[2]; int ans1 = 0,ans2 = 0; int XORsum = 0; for(int i = 0 ; i < array.length ; i++){ XORsum ^= array[i]; } int t = 1;//找出异或和中哪一位是1 while((XORsum&t)==0){ t<<=1; } for(int i = 0 ; i < array.length ; i++){ if((t&array[i])==0){ ans1 ^= array[i]; } else{ ans2 ^= array[i]; } } if(ans1<ans2){ ans[0] = ans1; ans[1] = ans2; } else{ ans[0] = ans2; ans[1] = ans1; } return ans; } }
python
class Solution: def FindNumsAppearOnce(self , array ): # write code here XORsum = 0 for i in array: XORsum ^= i t = 1 while (XORsum&t)==0: t= t<<1 ans1 = 0 ans2 = 0 for i in array: if (t&i)==0: ans1 ^= i; else: ans2 ^= i; if ans1<ans2: return [ans1,ans2] else: return [ans2,ans1]