题目描述
给定一个整数数组 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; } };