题目链接
思路:分组+异或
简化:如果整个数组中只有一个不重复的元素,全体异或一次就可
难点1:此时整个数组中,有两个,不能全体一起异或
解决难点1:如果我们可以将这整个数组分为两个数组,并且这两个不同的数字恰好分到不同的数组中,然后每个数组中只有一个不重复的元素,就可以了。
难点2:如何进行分组来保证两个不同的数字恰好到不同的数组中呢?
解决难点2:通过观察,可以发现,如果将一开始的数组全部异或,得到的肯定是一个不为0的数字,假设不同的数字为x y,那么将数组中的元素全部异或,得到的答案肯定等于x ^ y。
x异或y:分析一下,x ^ y != 0,那么他们在二进制中肯定存在一位或者多为不同的位
举例: 2 ^ 5 === 001 ^ 101 这里就是最高位的一位不同,想说的就是只要x ^ y不为0.那么肯定至少一位不同。
原理讲清楚了,那么继续解决难点2,如何分组呢,其实上面讲的就是x 与y的不同,即在某一位二进制中,至少有一个位,x与y是不同的,那么就根据这一位是否为0来分组
代码:
class Solution {
public int[] singleNumbers(int[] nums) {
int ag = 0;
for(int i = 0 ;i < nums.length;i++){
ag ^= nums[i];
}
//找到 x与y不同的某一位
int det = 1;
//寻找从左边往右第一个1
while ( (det & ag) != det ){//这个判断条件就是在判断 哪一位不同,这里要仔细想想
det <<= 1;//左移一位,即 一位一位的找,直到找到某一位他们不同
}
int res1 = 0;
int res2 = 0;
for(int i = 0; i < nums.length;i++){
if( (nums[i]&det)==det){
res1 ^= nums[i];
}else{
res2 ^= nums[i];
}
}
return new int[]{res1,res2};
}
}