题目描述:

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

思路分析:

1. 直接想法,每个数字遍历,统计出现次数,复杂度O(n^2),超时。

2. 借助哈希表,空间换时间,遍历一次,时间复杂度O(n),空间复杂度O(n),对于空间复杂度限制为O(1)时,不满足条件。

3. 利用异或运算。已知两个相同的数,异或为0。若当前的题目是只求一个只出现一次的数字时,只需要将数组中的数字都异或一次,最后得到的即为所求的只出现一次的数字。那么拓展到两个数字的情况,

我们可以将原始数组分成两个子数组,使得每个子数组包含一个只出现一次的数字,而其他数字都成对出现。这样,我们就可以用上述方法找到那个孤苦伶仃的元素。

我们还是从头到尾一次异或数组中的每一个数字,那么最终得到的结果就是两个只出现一次的数组的异或结果。因为其他数字都出现了两次,在异或中全部抵消了。由于两个数字肯定不一样,那么异或的结果肯定不为0,也就是说这个结果数组的二进制表示至少有一个位为1。我们在结果数组中找到第一个为1的位的位置,记为第n位。现在我们以第n位是不是1为标准把元数组中的数字分成两个子数组,第一个子数组中每个数字的第n位都是1,而第二个子数组中每个数字的第n位都是0。

举例:{2,4,3,6,3,2,5,5}

我们依次对数组中的每个数字做异或运行之后,得到的结果用二进制表示是0010。异或得到结果中的倒数第二位是1,于是我们根据数字的倒数第二位是不是1分为两个子数组。第一个子数组{2,3,6,3,2}中所有数字的倒数第二位都是1,而第二个子数组{4,5,5}中所有数字的倒数第二位都是0。接下来只要分别两个子数组求异或,就能找到第一个子数组中只出现一次的数字是6,而第二个子数组中只出现一次的数字是4。

代码:

思路二:

 class Solution {
public:
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
if(data.size()<=)
return;
map<int, int> data_map;
for(int i=; i<data.size(); i++)
{
data_map[data[i]]++;
}
vector<int> v;
for(int i=; i<data.size(); i++)
{
if(data_map[data[i]]==)
v.push_back(data[i]);
}
*num1 = v[];
*num2 = v[];
}
};

思路三:

class Solution {
public:
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
int length = data.size();
if(length<)
return;
//对原始数组求异或
int resultExclusiveOR = ;
for(int i=; i<length; i++)
resultExclusiveOR ^= data[i]; unsigned int indexOf1 = FindFirstBitIs1(resultExclusiveOR);
*num1 = ;
*num2 = ;
for(int j=; j<length; j++)
{
if(IsBit1(data[j], indexOf1))
{
*num1 ^= data[j];
}
else
{
*num2 ^= data[j];
}
}
}
private:
//找到二进制数num第一个为1的位数,如0010,第一个为1的位数是2
unsigned int FindFirstBitIs1(int num)
{
unsigned int indexBit = ;
//只判断一个字节的
while((num & )== && (indexBit < *sizeof(unsigned int)))
{
num = num >> ;
indexBit++;
}
return indexBit;
}
//判断第indexBit位是否为1
bool IsBit1(int num, unsigned int indexBit)
{
num = num >> indexBit;
return (num & );
}
};

最新文章

  1. Smart Tag——DevExpress WPF初探
  2. jQuery中width、innerWidth、outerWidth的区别
  3. mybatis自增长插入id
  4. 有关DTCoreText无法加载网络图片及应用问题
  5. html和css的联系
  6. UTF-8 有BOM和无BOM
  7. J - Fire!
  8. C语言原码反码补码与位运算.
  9. coordinate transformation
  10. GridView规则显示图片
  11. Webpack+Vue+ES6 前端组件化开发mobile-multi-page应用实战总结
  12. 文本分类学习 (五) 机器学习SVM的前奏-特征提取(卡方检验续集)
  13. [20190402]Library Cache mutex.txt
  14. go 终端读写、文件读写
  15. Kaldi如何统计data数据集
  16. js中的 !! 和 ! 的区别
  17. (转)JavaWeb学习之Servlet(三)----Servlet的映射匹配问题、线程安全问题
  18. webpack window dev-server配置
  19. 使用windowAnimations定义Activity及Dialog的进入退出效果
  20. PHP error_reporting() 函数

热门文章

  1. 使用kubeadm部署k8s
  2. OpenStack共享组件-RabbitMQ消息队列
  3. 用java刷剑指offer(数组中只出现一次的数字)
  4. Gorgeous Sequence(HDU5360+线段树)
  5. httprunner学习1-环境与登录接口案例
  6. windows 上运行 sslocal 提示 libcrypto(OpenSSL) not found 解决办法
  7. eclipse正常启动,debug无法启动,解决办法
  8. ThinkPHP远程调用模块的操作方法 URL 参数格式
  9. C#笔记2 —常量
  10. LeetCode 826. Most Profit Assigning Work