zoukankan      html  css  js  c++  java
  • 剑指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. };






  • 相关阅读:
    bzoj 3262: 陌上花开
    hdu 5618 Jam's problem again
    bzoj 1176: [Balkan2007]Mokia
    bzoj 2683: 简单题
    Codevs 1080 线段树练习(CDQ分治)
    bzoj 3223: Tyvj 1729 文艺平衡树
    bzoj 1503: [NOI2004]郁闷的出纳员
    bzoj 1208: [HNOI2004]宠物收养所
    bzoj 1588: [HNOI2002]营业额统计
    bzoj 3224: Tyvj 1728 普通平衡树
  • 原文地址:https://www.cnblogs.com/zhxshseu/p/5285004.html
Copyright © 2011-2022 走看看