题目链接
题目描述
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
示例 1:
输入:nums = [4,1,4,6]
输出:[1,6] 或 [6,1]
示例 2:
输入:nums = [1,2,10,4,1,4,3,3]
输出:[2,10] 或 [10,2]
限制:
2 <= nums.length <= 10000
思路
因为题目说其它数字都出现了两次,而两个相同的数字异或会得到0,因此我们可以先遍历一次整个数组,让所有数字一起进行异或操作,最终的结果diff相当于让我们要找的两个数字进行了异或。
接下来我们需要抽取出diff中任意为1的一位来进行分组异或,即下面代码中得到的div。
之所以用diff中任意为1的一位来进行分组是因为:diff相当于要找的两个数字进行了异或,所以diff中为1的位可以保证将两个数字分到不同组;而其它任意两个相同的数字必然被分到同一组,且异或的结果保持为0。
再次遍历整个数组,对每个数字判断与div的并运算结果是否为0,如果为0就属于组1,否则属于组2,并将该数字与对应的组的ans进行异或,最终组1、组2的ans就是答案。
代码如下:
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int diff=0,div=1,ans1=0,ans2=0;
//所有数字一起异或
for(int i:nums)
diff^=i;
//找出diff中任意为1的一位
while((div&diff)==0)
div<<=1;
//分组异或
for(int i:nums){
if((div&i)==0)
ans1^=i;
else
ans2^=i;
}
return vector<int>{ans1,ans2};
}
};