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

一个整型数组里除了两个数字之外,其他的数字都出现了两次(想到异或性质:任意数字和自己异或都是0,这样每个数字从头到尾异或一遍,出现两次的数字都被消掉了。请写程序找出这两个只出现一次的数字。
要求时间复杂度O(n),空间复杂度O(1)。
异或运算符:^
分析:
利用异或的性质;
异或每个数字,最后的结果是两个不同数字的异或结果。
想办法把两个不同的数字分到两个数组中,分别异或;

分组的方法:
  1. 把所有数字在二进制下看
  2. 成对的数字,所有bit都相同;
  3. 根据所有数字异或的结果,转为2进制,其结果等效于两个不同数字的异或;
  4. 找到该结果中,某个为1的bit位;假设为第n位;也就是说,这两个不同的数字,第n位是不相同的。
  5. 根据第n位是0,还是1,分为两个数组;这样两个不同的数字就分到了两组;显然成对的数字仍然会在同一组;
  6. 分别异或两个数组即可。
  1. class Solution {
  2. public:
  3. void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
  4. int size=data.size();
  5. if(size<2)return;
  6. int result=data[0];
  7. for(int i=1;i<size;i++){
  8. result=result^data[i];
  9. }
  10. int n=0;
  11. while(!(result&0x01)){
  12. result=result>>1;
  13. n++;
  14. if(n>32)return;
  15. }
  16. int mask=0x01<<n;
  17. *num1=0;*num2=0;
  18. for(int i=0;i<size;i++){
  19. if(data[i]&mask)
  20. *num1^=data[i];
  21. else
  22. *num2^=data[i];
  23. }
  24. }
  25. };






posted @ 2016-03-16 20:30  copperface  阅读(219)  评论(0编辑  收藏  举报