題目:算法
一個整型數組裏除了兩個數字以外,其餘的數字都出現了兩次。請寫程序找出這兩個只出現一次的數字。數組
看題目腦子裏就出現作法了:spa
遍歷,用個HashMap來記錄出現的次數,而後再遍歷HashMap返回的EntrySet找出出現一次的數字搞定。code
代碼順便上下吧:blog
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) { HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); Integer count; for(int temp : array) { if( (count = map.get(temp)) == null )map.put(temp, 1); else map.put(temp, ++count); } num1[0] = -1;num2[0] = -1; Set<Entry<Integer, Integer>> entrySet = map.entrySet(); for(Entry<Integer, Integer> temp : entrySet) { if( (count = temp.getValue()) == 1 && num1[0] == -1)num1[0] = temp.getKey(); else if(count == 1)num2[0] = temp.getKey(); } }
而後看牛客網的討論,原來能夠用異或操做很帥氣地解決這個問題哈哈,來記錄一下。get
基礎知識:it
思路:(來自牛客的一個小夥子)io
而後上一下我本身根據這個思路寫的代碼,已經經過:class
/*高端的位運算法*/ public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) { int firstXorResult = 0;//0和任何數異或都爲自己 for(int temp : array) { firstXorResult ^= temp;//異或知足結合率,a^b^a = b } //這樣獲得的firstXorResult就是惟一兩個只出現一次的數字的亦或結果,也就是這個firstXorResult中爲1的地方,就是這兩個數字在位上面不一樣的地方 int shiftBit = 0; while(shiftBit <= 31) {//這個循環是看從最低位開始,哪一個位是第一個不一樣的,也就是爲1的 if( (firstXorResult & (1 << shiftBit)) != 0 )break; shiftBit++; } List<Integer> list1 = new ArrayList<Integer>(); List<Integer> list2 = new ArrayList<Integer>(); for(int temp : array) { //根據剛剛的shiftBit,把數字分紅兩份,一份相與爲0,一份不爲0。首先確定那兩個只出現一次的數字確定分開的;而後相同的數字確定分到一個list if( (temp & (1 << shiftBit)) == 0 ) { list1.add(temp); } else { list2.add(temp); } } int result1 = 0, result2 = 0; for(int temp : list1) {//異或結束獲得的就是結果 result1 ^= temp; } for(int temp : list2) { result2 ^= temp; } num1[0] = result1; num2[0] = result2; }