【剑指】56(1).数组中只出现一次的两个数字
程序员文章站
2022-07-15 12:12:09
...
题目描述
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
算法分析
- 首先:位运算中异或的性质:两个相同数字异或=0,一个数和0异或还是它本身。
- 当只有一个数出现一次时,我们把数组中所有的数,依次异或运算,最后剩下的就是落单的数,因为成对儿出现的都抵消了。
- 依照这个思路,我们来看两个数(我们假设是AB)出现一次的数组。我们首先还是先异或,剩下的数字肯定是A、B异或的结果,这个结果的二进制中的1,表现的是A和B的不同的位。我们就取第一个1所在的位数,假设是第3位,接着把原数组分成两组,分组标准是第3位是否为1。如此,相同的数肯定在一个组,因为相同数字所有位都相同,而不同的数,肯定不在一组。然后把这两个组按照最开始的思路,依次异或,剩余的两个结果就是这两个只出现一次的数字。
提交代码:
class Solution {
public:
void FindNumsAppearOnce(vector<int> data, int* num1, int *num2) {
if (data.empty())
return;
int temp = 0;
for (auto iter = data.cbegin(); iter != data.cend(); ++iter)
temp ^= *iter;
// 找到最低位的第一个1
int i = 1;
while ((temp & i) == 0)
i <<= 1;
*num1 = *num2 = 0;
for (auto iter = data.cbegin(); iter != data.cend(); ++iter)
{
if ((*iter & i) == 0)
*num1 ^= *iter;
else
*num2 ^= *iter;
}
}
};
测试代码:
// ====================测试代码====================
void Test(const char* testName, vector<int> data, int expected1, int expected2)
{
if (testName != nullptr)
printf("%s begins: ", testName);
int result1, result2;
Solution s;
s.FindNumsAppearOnce(data, &result1, &result2);
if ((expected1 == result1 && expected2 == result2) ||
(expected2 == result1 && expected1 == result2))
printf("Passed.\n\n");
else
printf("Failed.\n\n");
}
void Test1()
{
vector<int> data = { 2, 4, 3, 6, 3, 2, 5, 5 };
Test("Test1", data, 4, 6);
}
void Test2()
{
vector<int> data = { 4, 6 };
Test("Test2", data, 4, 6);
}
void Test3()
{
vector<int> data = { 4, 6, 1, 1, 1, 1 };
Test("Test3", data, 4, 6);
}
int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
return 0;
}
推荐阅读
-
PHP查找数组中只出现一次的数字实现方法【查找特定元素】
-
剑指offer 56 数组中数字出现的次数 lintcode 82. 落单的数、83. 落单的数 II、84. 落单的数 III
-
【知识迁移能力】数组中只出现一次的数字
-
【不熟练】知识迁移能力-数组中只出现一次的数字
-
数组中只出现一次的数字( 知识迁移能力)
-
刷题--数组中只出现一次的数字
-
【剑指offer】面试题56(1):数组中只出现一次的两个数字
-
剑指offer:数组中只出现一次的两个数字(java版)
-
剑指offer 面试题56 python版+解析:数组中只出现一次的两个数字,数组中唯一只出现一次的数字
-
剑指offer第二版-56.数组中只出现一次的两个数字