只出现一次的数字 III
题目描述
给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。
示例 :
输入: [1,2,1,3,2,5] 输出: [3,5]
注意:
结果输出的顺序并不重要,对于上面的例子, [5, 3] 也是正确答案。 你的算法应该具有线性时间复杂度。你能否仅使用常数空间复杂度来实现?
题解:
(1)常用公式:
(1) a=0^a=a^0
0=a^a
=> a=a^b^b
(2) 交换a和b
a=a^b
b=a^b
a=a^b
(3) 移除最后一个 1
a=n&(n-1)
(4) 获取最后一个 1
diff=(n&(n-1))^n = n&(-n)(2)代码:
class Solution {
public:
vector<int> singleNumber(vector<int>& nums) {
//得到两个只出现一次的数的异或,因为0=a^a
int res = 0;
for(auto& e : nums)
res^=e;
//这两个数一定是不一样的,所以他们异或后的二进制表达式肯定存在1, 且这个1要么来自a, 要么来自b
//通过res&(-res)来提取其中一个1出来,6的补码:0110, -6的补码:1010
res = res&(-res);
vector<int> r(2,0);
//将nums中的元素通过与res进行与运算来将a和b进行分开
for(auto& e:nums)
if(e&res)
r[0]^=e;
else
r[1]^=e;
return r;
}
};