题目描述:
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
方法一:哈希法
- 遍历一遍数组,用map记录出现的次数,再遍历一遍数组,找出出现1次的数字
- 时间复杂度:O(n)
- 空间复杂度:O(n)
public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
Map<Integer,Integer> map = new LinkedHashMap();
for (int i : array){
if (map.containsKey(i)){
int val = map.get(i);
map.put(i,++val);
}else {
map.put(i,1);
}
}
int i = 0;
Iterator iterator = map.entrySet().iterator();
while(iterator.hasNext()){
Map.Entry entry = (Map.Entry) iterator.next();
int value = (int) entry.getValue();
if (value == 1){
if (i == 0){
num1[0] = (int) entry.getKey();
i = 1;
}else {
num2[0] = (int) entry.getKey();
}
}
}
// System.out.println(num1[0] + " " + num2[0]);
}
方法二:位运算【不懂】
- 异或运算:如果a、b两个值不相等,则异或结果为1。如果a、b两个值相同,则异或结果为0。
- n^0 = n;
- n^n = 0;
- n ^ n ^ m = n ^ (n^m)
- 我们让数组中的每个数异或一下, 最后会得到结果ret,就是两个出现一次的数字的抑或结果这个结果肯定是由两个不同数字异或而来的,因此我们找ret二进制中为1的位置i,因为1一定是由0,1异或而来,因此要求的两个数中,一定有一个数的二级制中的第i个位置为1,一个为0。