数组中只出现一次的数


这个题目的思想是,书上说,由于题目中说了是其它的数字有两个,而这两个数字
只有一个,于是知:异或(不知道你有没有想到)。
解题的思路是:
    先对数组中所有数字进行一次异或
  1.     int bitXORResult=0;
  2. for(int i=0;i<Length; i++){
  3. bitXORResult^=arr[i];
  4. }
那么知道其实这个bitXORResult最后的结果就是那两个只出现一次的数字的异或的结果。也就4^6=2啰。
2也就是0X10嘛。
然后。我们将这个数组分成两个数组:怎么分?
根据这些数字的二进制表示的倒数第2位是不是1来分(因为bitXORResult=0x10).于是知,
  1. int lastBitOne=findLastBitsOne(bitXORResult); //找到了从最后一位开始找为1的位


  2. int findLastBitsOne(int v_bitsResult){
  3. int shiftCount=0;
  4. int bit=1;
  5. while(v_bitsResult^bit==1){
  6. shiftCount++;
  7. v_bitsResult=v_bitsResult>>1;
  8. }
  9. return shiftCount;
  10. }
找到bitXORResult中从最后开始最近一位是1的下标。

然后就根这个标志分成两组。那么这两个只出现一次的数组肯定出现在不同的数组中。我们知道由于其它的数字都是
成对出现的。那么对应的位要么是1,要么是0.那么其它的数字肯定成对出现在这些数组中啊,就像如下:
分成的数组1:2、3、6、3、2
分成的数组2:4、5、5
那有没有可能4、6(只出现一次)同时出现在同一个数组中呢? 不可能,为啥 ?
如果4、6同时出现在同一个数组中,也就是4、6对应的那位是相同啰。那么异或之后还是0罗。而其它数字对应的那个位是成对出现的(因为出现两次嘛)
于是它们的异或后结果也是0嘛。于是那么位不可能是1啊。与假设相矛盾。
那么只有可能是有一个只现一次的数中其对应的那个位是1(也就是数组中的6),另一个(4)对应的那位0罗。
  1. ifndef ONE_TIME_ARR_H
  2. #define ONE_TIME_ARR_H
  3. #include<iostream>
  4. int findLastBitsOne(int v_bitsResult);
  5. bool isBitOne(int value,int bitIndex);
  6. void findNumsApprenceOnce(int *arr,int Length,int *num1,int *num2){
  7. if(arr==NULL||Length<=2){
  8. return;
  9. }
  10. int bitXORResult=0;
  11. for(int i=0;i<Length; i++){
  12. bitXORResult^=arr[i];
  13. }
  14. if(0==bitXORResult){
  15. return;
  16. }
  17. int lastBitOne=findLastBitsOne(bitXORResult); //找到了从最后一位开始找为1的位
  18. *num1=0;
  19. *num2=0;
  20. for(int i=0;i<Length; i++){
  21. if(isBitOne(arr[i],lastBitOne)){
  22. (*num1)^=arr[i];
  23. }else{
  24. (*num2)^=arr[i];
  25. }
  26. }
  27. }
  28. int findLastBitsOne(int v_bitsResult){
  29. int shiftCount=0;
  30. int bit=1;
  31. while(v_bitsResult^bit==1){
  32. shiftCount++;
  33. v_bitsResult=v_bitsResult>>1;
  34. }
  35. return shiftCount;
  36. }
  37. bool isBitOne(int value,int bitIndex){
  38. value=value>>bitIndex;
  39. return (value&1);
  40. }
  41. #endif








posted @ 2015-07-17 19:22  yml435  阅读(335)  评论(0编辑  收藏  举报