剑指offer40_数组中只出现一次的数字_题解
数组中只出现一次的数字
题目描述
一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
分析
方案一:分组异或
先对所有数字进行一次异或,得到两个出现一次的数字的异或值。
在异或结果中找到任意为 1 的位。
根据这一位将所有的数字分成两组。
在每个组内进行异或操作,得到两个数字。
代码
/**
1.时间复杂度:O(n)
只需要遍历数组两次。
2.空间复杂度:O(1)
只需要常数的空间存放若干变量。
**/
class Solution
{
public:
void FindNumsAppearOnce(vector<int> data, int *num1, int *num2)
{
int ret = 0;
for (int n : data)
ret ^= n;
int div = 1;
while ((div & ret) == 0)
div <<= 1;
int a = 0, b = 0;
for (int n : data)
{
if (div & n)
a ^= n;
else
b ^= n;
}
*num1 = a, *num2 = b;
}
};
方案二:哈希
第一次遍历用一个哈希数组存储每个数字是否重复出现,为真没有重复出现,为假则重复出现
第二次遍历判断哈希数组值是否为真,为真则为所求数字,加入结果集合
代码
/**
1.时间复杂度:O(n)
2.空间复杂度:O(n)
**/
class Solution
{
public:
void FindNumsAppearOnce(vector<int> data, int *num1, int *num2)
{
map<int, bool> dic;
for (int k : data)
{
dic[k] = dic.find(k) == dic.end();
}
int cnt = 1;
for (int k : data)
{
if (dic[k])
{
if (cnt == 1)
{
*num1 = k;
}
if (cnt == 2)
{
*num2 = k;
}
++cnt;
}
}
}
};