zoukankan      html  css  js  c++  java
  • 剑指offer——数组中只出现一次的数字

    1、一个数字出现一次,其他数字出现两次

    两个相同的数异或为0,所以将数组里的所有数依次异或,得到的结果就是只出现一次的数。

    #include <iostream>
    using namespace std;
    int main()
    {
        int a[]={3,6,2,3,2,5,5};
        int num=0;
        for(int i=0;i<7;i++)
        {
            num^=a[i];
        }
        cout<<num<<endl;
        return 0;
    }

    2、一个数字出现一次,其他数字出现N次

    通过观察法,发现如果数字出现了n次,那么每一bit位之和可以被n整除。

    #include <iostream>
    #include <string>
    using namespace std;
    int FindNumber(int a[], int n, int m)
    {
      int bits[32];
      int i, j;
      // 累加数组中所有数字的二进制位
      memset(bits, 0, 32 * sizeof(int));
      for (i = 0; i < n; i++)
        for (j = 0; j < 32; j++)
          bits[j] += ((a[i] >> j) & 1);
      // 如果某位上的结果不能被整除,则肯定目标数字在这一位上为
      int result = 0;
      for (j = 0; j < 32; j++)
        if (bits[j] % m != 0)
          result += (1 << j);
      return result;
    }
    int main()
    {
      int a[] = {2, 3, 1, 2, 3, 4, 1, 2, 3, 1};
      //3代表其他数字出现3次
      cout<<FindNumber(a, 10, 3)<<endl;
      return 0;
    }

    3、两个数字出现一次,其他数字出现两次

    和1的原理差不多,先是分别异或,得到结果,肯定不为0。找到结果1所在的位置x,将原数组分为两部分,第一部分是x为1的数的集合,第二部分是x为0的数的集合。然后分别对这两个数组异或,得到这两个出现一次的数。

    #include <iostream>
    #include <string>
    using namespace std;
    
    unsigned int FindFirstBitIs1(int num)
    {
        int indexBit=0;
        while(((num&1)==0)&&(indexBit<8*sizeof(int)))
        {
            num=num>>1;
            ++indexBit;
        }
        return indexBit;
    }
    
    bool IsBit1(int num,unsigned int indexBit)
    {
        num=num>>indexBit;
        return (num&1);
    }
    
    void FindNumsAppearance(int data[],int length,int *num1,int *num2)
    {
        if (data==NULL||length<2)
        {
            return;
        }
        int resultExclusiveOR=0;
        for (int i=0;i<length;i++)
        {
            resultExclusiveOR^=data[i];
        }
        unsigned int indexof1=FindFirstBitIs1(resultExclusiveOR);
        *num1=*num2=0;
        for (int j=0;j<length;j++)
        {
            if (IsBit1(data[j],indexof1))
            {
                *num1^=data[j];
            }
            else
            {
                *num2^=data[j];
            }
        }
    }
    
    int main()
    {
        int a[]={4,3,6,3,2,5,5};
        int temp1,temp2;
        FindNumsAppearance(a,7,&temp1,&temp2);
        cout<<temp1<<"	"<<temp2<<endl;
        return 0;
    }

    参考:

    http://blog.csdn.net/morewindows/article/details/12684497

  • 相关阅读:
    android 监听ListView中的 item 和button
    android 获取当前系统及应用信息(二)
    MotionEvent中getX()和getRawX()的区别
    HITS 算法(Hypertext Induced Topic Selection)
    放之四海皆适用的设计原则(二)
    源自神话的写作要义之英雄之旅
    这就是搜索引擎:核心技术详解
    源自神话的写作要义之英雄
    使用Spinner和setDropDownViewResource
    友好界面menu
  • 原文地址:https://www.cnblogs.com/dgy5554/p/3973383.html
Copyright © 2011-2022 走看看