剑指 Offer 56 - I. 数组中数字出现的次数
一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
思路:由于时间复杂度和空间复杂度的要求,首先排除 暴力法 和 哈希表统计法 。
因为相同的数字异或为0,任何数字与0异或结果是其本身。所以遍历异或整个数组最后得到的结果就是两个只出现一次的数字异或的结果:即 z = x ^y
根据异或的性质:z中至少有一位是1,否则x与y就是相等的。
我们通过一个辅助变量m来保存z中哪一位为1.(可能有多个位都为1,我们找到最低位的1即可)
遍历数组,将每个数跟m进行与操作,结果为0的作为一组,结果不为0的作为一组
分别对nums1和nums2遍历异或就能得到x和y
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int ret = 0;
for (int n : nums)
ret ^= n;
int m = 1;
while ((m & ret) == 0)
m <<= 1;
int a = 0, b = 0;
for (int n : nums)
if (m & n)
a ^= n;
else
b ^= n;
return vector<int>{a, b};
}
};