Given an array of numbers nums
, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.
For example:
Given nums = [1, 2, 1, 3, 2, 5]
, return [3, 5]
.
题目:给一个数组,数组里面有相同的元素,有不同的元素,每组相同的元素刚好有两个,不同的元素也是刚好两个
思路:1,之前没认真看题目的条件,导致写了一套通用的,不管相同元素有多少个,代码优化之如下:
public int[] singleNumber(int[] nums) {
int len = nums.length;
Map<Integer,Integer> countMap = new HashMap<Integer,Integer>();
for(int i = 0;i<len;i++){
Integer count = countMap.get(nums[i]);
if(count==null){
countMap.put(nums[i],1);
}else{
countMap.put(nums[i],count+1);
}
}
int[] res = new int[2];
int i = 0;
for(Entry e :countMap.entrySet()){
if((Integer)e.getValue()==1){
res[i++] = (Integer)e.getKey();
}
}
return res;
}
更符合题意的思路2:
思路2主要是根据逻辑位运算的特点:因为题意是每一组相同元素的个数只有两个,那么我们只要把它们异或XOR运算一下,就为0了,将数组所有的数逐一进行异或运算,最后得到的就是两个不同的元素的异或的结果,可以根据这个结果取其二进制形式中的某一位1,为什么去1呢,因为异或运算就是相同为0,不同为1,这个可以区分的是两个不同数,区分出来了,over。。。
public int[] singleNumber(int[] nums) {
int distinct = 0,len = nums.length;
for(int i = 0;i <len;i++){
distinct ^= nums[i];
}
distinct &=-distinct;
int res [] = new int[2];
for(int i = 0;i<len;i++){
if((res&nums[i])==0){
res[0] ^=nums[i];
}else{
res[1]^=nums[i];
}
}
return res;
}
runtime居然2ms,比我之前那个是快多了,说实话,这个道题让我感觉到了编程的快乐