示例1
输入:[1,4,1,6]
返回值:[4,6]
说明:返回的结果中较小的数排在前面
示例2
输入:[1,2,3,3,2,9]
返回值:[1,9]
这个题的解法,可以参考 “剑指offer(三十四)-第一个只出现一次的字符”这篇文章。
第一种解法
使用一个map来进行存储,遍历完成以后,取出次数为1的数据即可。代码如下
public int[] firstFindNumsAppearOnce (int[] array) {
int[] result = new int[2];
int count = 2;
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < array.length; i++) {
int a = array[i];
if(map.get(a) != null){
map.put(a,2);
}else {
map.put(a,1);
}
}
for (Integer key : map.keySet()){
Integer integer = map.get(key);
if(integer.equals(1)){
result[--count] = key;
}
}
if(result[0] > result[1]){
int tmp = result[1];
result[1] = result[0];
result[0] = tmp;
}
return result;
}
第二种解法
把数字全异或起来,最后异或出来的结果是不同的那两个数的异或,然后随便从异或结果里面找一位1,因为某一位上异或结果是1的话,说明要找两个数,这一位上一个是1,一个是0。那么就可以把原来数组中,这一位是1的分成一组,这一位是0的分成一组。这样就有了两组每一组中会包含一个不同的数和一部分出现两次的数。 然后组内异或就可以了,代码如下
public int[] secondFindNumsAppearOnce (int[] array) {
int[] result = new int[2];
int count = 2;
int x = 0;
for (int i = 0; i < array.length; i++) {
x ^= array[i];
}
//找出异或和中哪一位是1
int m = 1;
while ((m & x) == 0){
m = m<<1;
}
for (int i = 0; i < array.length; i++) {
if((m & array[i]) == 0){
result[0] ^=array[i];
}else {
result[1] ^=array[i];
}
}
if(result[0] > result[1]){
int tmp = result[1];
result[1] = result[0];
result[0] = tmp;
}
return result;
}