问题描述
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
解题报告
- 分组异或
如果只有一个数字出现一次,其他数字出现偶数次,那么将所有数进行异或,最后结果即为所求。
但是现在有两个数只出现一次,其他数出现两次。
解决方式:
设只出现一次的数为a,b
。将所有数进行异或,结果为a和b的异或结果,我么记为x
。x
的二进制形式为
x
k
x
k
−
1
⋯
x
1
x
0
x_{k}x_{k-1}\cdots x_{1}x_{0}
xkxk−1⋯x1x0,其中
x
∈
{
0
,
1
}
x \in\{0,1\}
x∈{0,1}
x
i
=
0
x_i=0
xi=0意味着
a
i
a_i
ai和
b
j
b_j
bj相等;
x
i
=
1
x_i=1
xi=1意味着
a
i
a_i
ai和
b
j
b_j
bj不等;
我们任选一个不为0的 x i x_i xi,按照第i为来给原来的序列分组,如果该位为0就分到第一组,否则分到第二组,这样就能将相同的数分到相同的一组,数组中不相等的两个数分到不同的数。
实现代码
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int ret = 0;
for (int n : nums)
ret ^= n;
int div = 1;
while ((div & ret) == 0)
div <<= 1;
int a = 0, b = 0;
for (int n : nums)
if (div & n)
a ^= n;
else
b ^= n;
return vector<int>{a, b};
}
};
// 作者:LeetCode-Solution
// 链接:[https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/solution/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-by-leetcode/](https://leetcode-cn.com/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/solution/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-by-leetcode/)
// 来源:力扣(LeetCode)
// 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
参考资料
[1] Leetcode 面试题56-I. 数组中数字出现的次数
[2] 题解区:官方答案