面試題56.2:數組中唯一只出現一次的數字
題目要求:
在一個整數數組中除了一個數字只出現一次外,其他數字都出現三次。找出那個出現一次的數字。
解題思路:
如果題目中的“三次”換成“兩次”,這道題目將非常簡單,因此兩個相同的數字異或,每一位都會變成0,其實亦或也可以看成兩個數字的每一個二進制位對應進行加法后對2取模后的結果。按照這種思路,對于出現三次的數字,改成對3取模即可。舉個例子說明下(10,4,5,5,4,4,5):
相關數字對應二進制表示:10 = 1010 4 = 0100 5 = 0101
1)申請一個長度為32(因為int占32bit)的int型數組bitsum,用于記錄整型數字每一位出現1的次數。
bitsum = 00000000 00000000 00000000 00000000
2)將每個數字計入到bitsum[]中
10-> 00000000 00000000 00000000 00001010
4 -> 00000000 00000000 00000000 00001110
5 -> 00000000 00000000 00000000 00001211
5 -> 00000000 00000000 00000000 00001312
4 -> 00000000 00000000 00000000 00001412
4 -> 00000000 00000000 00000000 00001512
5 -> 00000000 00000000 00000000 00001613
3)bitsum的每一個元素對3取模:
bitsum = 00000000 00000000 00000000 00001010
4)將bitsum作為一個32bit的整數:
result = 00000000 00000000 00000000 00001010 = 10
代碼實現:
package chapter6;
/**
* Created with IntelliJ IDEA
* Author: ryder
* Date : 2017/8/17
* Time : 11:54
* Description:數組中唯一只出現一次的數字
* 一個數字出現一次,其他的都出現三次,找到那一個數字
**/
public class P278_NumberAppearOnce {
public static int findNumberAppearOnce(int[] data){
if(data==null ||data.length<3)
return 0; //為了方便返回0,但其實并不能區分異常
// 存儲一個int(長度32bit)的每個bit的狀態
int[] bitSum = new int[32];
int k = 3;
for(int i=0;i<data.length;i++){
int indexOfBit1 = 1;
for(int j=31;j>=0;j--){
if((data[i]&indexOfBit1)!=0)
bitSum[j] += 1;
indexOfBit1<<=1;
}
}
int result = 0;
for(int i=0;i<32;i++){
result<<=1; //先移位
result+=bitSum[i]%k;
}
return result;
}
public static void main(String[] args){
int[] data1 = new int[]{10,4,5,3,5,4,3,3,4,5};
int[] data2 = new int[]{0,-4,5,3,5,-4,3,3,-4,5};
int[] data3 = new int[]{-10,-4,5,3,5,-4,3,3,-4,5};
System.out.println(findNumberAppearOnce(data1));
System.out.println(findNumberAppearOnce(data2));
System.out.println(findNumberAppearOnce(data3));
}
}
運行結果:
10
0
-10