一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
解题思路
- 加入一个辅助HashMap
- 位运算之异或的特点(很妙)
上代码(C++很香)
法一:加入HashMap
public void FindNumsAppearOnce(int[] array, int num1[], int num2[]) {
HashMap<Integer, Integer> map = new HashMap<>();
for(int i = 0 ; i < array.length; i++) {
if(map.containsKey(array[i]))
map.put(array[i], map.get(array[i]) + 1);
else
map.put(array[i], 1);
}
int i = 0;
for(Integer key : map.keySet()) {
if(map.get(key) == 1)
array[i++] = key;
}
num1[0] = array[0];
num2[0] = array[1];
}
法二:异或运算的特点
如果数组中只有一个数子出现一次,其它数字都出现两次,那么将这个数组异或到底,最后剩下的值就是那个出现一次的数字。
int FindFirstBitIs1(int num){
int index = 0;
while((num & 1) == 0 && (index < 8 * sizeof(int))){
num = num >> 1;
index++;
}
return index;
}
bool IsBit1(int num, int index){
num = num >> index;
return (num & 1);
}
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
if(data.size() < 2)
return ;
int resultOR = 0;
for(int i = 0; i < data.size(); i++)
resultOR ^= data[i];
int indexOf1 = FindFirstBitIs1(resultOR);
*num1 = *num2 = 0;
for(int i = 0; i < data.size(); i++){
if(IsBit1(data[i], indexOf1))
*num1 ^= data[i];
else
*num2 ^= data[i];
}
}