【剑指offer】数组中只出现一次的数字

雨点打透心脏的1/2处 2023-07-19 04:48 44阅读 0赞

题目描述

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

思路

首先这道题本可以直接对所出现的数进行计数,然后输出数组中只出现一次的两个数字。

但是题上特地说了一下其他数字都出现了两次,说明题意是想考察的是另一个知识点:

位运算中的异或运算:两个相同的数进行异或时,结果为0

因此如果我们从头到尾依次异或数组中的每一个数字,那么最终得到的结果就是两个只出现一次的数字的异或结果,

由于这两个数字不一样,那么这个异或结果肯定不为0 ,也就是说在这个结果数字的二进制表示中至少就有一位为1 ,

我们在结果二进制中保留最高位的1(假设为第N位),并将其它的都置为0,然后拿这个数与原数组进行与运算,

这样原数组就会被我们分为两个子数组,第一个子数组中每个数的第N 位都为1 ,而第二个子数组的每个数的第N 位都为0 。

现在我们已经把原数组分成了两个子数组,而只出现一次的两个数字也被我们分到了两个不同的子数组中,

因此再对两个子数组进行异或之后就可以得出最终的结果了,而且题上并没有说明要按顺序找出这两个数字,

那么到此为止,问题就被我们解决了。

代码

  1. class Solution {
  2. public:
  3. void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
  4. if(data.empty())
  5. return;
  6. int x = 0;//用于保存num1和num2的异或结果
  7. for(int i = 0; i < data.size(); i++)
  8. x ^= data[i];
  9. int t = 1;//保留x中第一个1的位置,其它都置为0
  10. while(x>>1){
  11. t *= 2;
  12. x = x>>1;
  13. }
  14. *num1 = *num2 = 0;
  15. for(int i = 0; i < data.size(); i++){
  16. if(t & data[i]){
  17. *num1 ^= data[i];
  18. }
  19. else
  20. *num2 ^= data[i];
  21. }
  22. return;
  23. }
  24. };

发表评论

表情:
评论列表 (有 0 条评论,44人围观)

还没有评论,来说两句吧...

相关阅读