题目链接: leetcode.
妙啊妙,太强了(๑•̀ㅂ•́)و✧
要求时间O(n) 空间O(1)
- 一个不同的数是可以通过异或解出来的,两个不同的数可以把这两个数放在不同的组中,这样就又化解为求一个不同的数了。
- 怎么将这两个数分在两个组里,且组内其他数都出现了两次呢?
- 1.全部异或得到两个不同的数的异或值
x
; - 2.
x
的每一位表示,这两个不同的数对应位的异或情况,所以为1
的位说明这两个数该位一定不同; - 3.所以可以记录某个为
1
的位,用来分组,与这个位&
为0
的数一组,&
为1
的数为一组。
- 1.全部异或得到两个不同的数的异或值
- 至此,两个不同的数分别被放入两个不同的组中,而组内的其他数也一定两两相同。
再说一遍,妙哉妙哉 。
/*
执行用时:20 ms, 在所有 C++ 提交中击败了82.58%的用户
内存消耗:15.5 MB, 在所有 C++ 提交中击败了98.57%的用户
*/
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int N = nums.size();
int x = 0;
for(auto i : nums)
{
x = x ^ i;
}
//记录两个数的异或中最低位的 1
int tmp = 1;
while((tmp & x) == 0) // == 运算符优先级高于 &,所以加括号
{
tmp = tmp << 1;
}
int ans1 = 0, ans2 = 0;
for(auto i : nums)
{
if((i & tmp) == 0)
ans1 ^= i;
else
ans2 ^= i;
}
return {ans1, ans2};
}
};