面试题56:数组中数字出现的次数

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

解题思路

  • 加入一个辅助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];
    }
}
posted @ 2020-08-24 10:55  程序员曾奈斯  阅读(121)  评论(0)    收藏  举报