立个flag 再不认真写思路是🐕
思路
1.两个相同的数异或结果为0,如果有一个只出现一次的数a,那么数组中所有数的异或结果为这个数a。
2.本题有两个只出现一次的数a和b,数组最后的异或结果就是这两个数异或的结果a^b。
3.如果将数组中的数分成两组,a、b分别在这两组,那么这两组数分别异或的结果就是a和b了。
4.问题是怎么分组呢
①先异或所有数,得到k=a^b
②需要找到a,b不一样的位置,即k中是1的位。
方法是 设置mark=1,若(mark&k)==0,mark左移一位
③遍历数组nums中的num并作异或^。(num&mark)==1为一组,异或结果为a;(nums&mark)==0为一组异或结果为b。
④返回数组{a,b}
代码
class Solution {
public int[] singleNumbers(int[] nums) {
int k=0;//异或所有的数
for(int i:nums){
k^=i;
}
int mark=1;//找到第一个是1的位
while((k&mark)==0){
mark=mark<<1;
}
int a=0;//第一个数
int b=0;//第二个数
for(int num:nums){
if((num&mark)==0){
a^=num;
}
else{
b^=num;
}
}
return new int[]{a,b};
}
}
复杂度
时间复杂度O(N) 空间复杂度O(1)