1.数组中数字出现的次数
(1)数组中只出现一次的两个数字
数组中只有两个数只出现了一次,剩下的都出现两次,要求时间O(n),空间O(1)。
思路:任何数异或自己都等于0.先将数组进行从头到尾的异或,得到的结果是两个数字的异或值,根据这个异或值第一个为1的位的位置,把数组分为两个数组,找出这两个数。

class Solution {
public:
    void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
      /*先考虑简化问题,如只有一个数字除外,则一次异或数组就可得到答案,本题有两个数字,因此考虑
        变成两个简化问题。
        在结果数字中找到第一个为1的位的位置,记为第N位。以第N位是不是1为标准把原数组中的数字分成
        两个子数组,第一个子数组中每个数字的第N位都为1,而第二个子数组的每个数字的第N位都为0 。
        现在我们已经把原数组分成了两个子数组,每个子数组都包含一个只出现一次的数字,而其它数字都
        出现了两次。因此到此为止,所有的问题我们都已经解决。*/
        int len=data.size();
        if(len<2) return;
        int temp=data[0];
        for(int i=1;i<len;i++)
            temp^=data[i];
        int index=findFirstBitIs(temp);//找异或得到的数的第一个为1的位置
        *num1=0,*num2=0;
        for(int i=0;i<len;i++)
        {
            if(isBit(data[i],index)==0)
                *num1^=data[i];//记录第N位都是0的
            else
                *num2^=data[i];//记录第N为都是1的
        }         
    }
     int findFirstBitIs(int num)//找第一个为1的位的位置
    {
       int indexBit = 0;
       while(((num & 1)==0) && (indexBit)<32)//如果按位与1得0,就右移一位
       {
           num = num >> 1;
           ++indexBit;
       }
       return indexBit;//得到从右到左第一个为1的位置
   }
     bool isBit(int num,int indexBit)
    {
       num = num >> indexBit;
       return (num & 1) == 1;//右移index位,和1与,要么相等要么不等
   }
};

(2)数组中唯一只出现一次的数字
在一个数组中除一个数字只出现一次之外,其他数字都出现了3次,找出这个数字。
思路:如果一个数字出现3次,那么它的二进制表示的每一位也出现三次。如果把所有出现三次的数字的二进制表示的每一位都分别加起来,那么每一位的和都能被3整除。将数组中所有数字的二进制表示的每一位都加起来,如果某一位的和能被3整除,那么那个只出现一次的数字二进制表示中对应的那一位就是0;否则就是1.

int FindNumber(int numbers[],int length)
{
    if(numbers==nullptr||length<=0)
       return 0;
    int bitSum[32]={0};
    for(int i=0;i<length;i++)
    {
        int bitMask=1;
        for(int j=31;j>=0;j--)
        {
            int bit=numbers[i]&bitMask;
            if(bit!=0)
            {
                bitSum[j]+=1;
            }
        }
        bitMask=bitMask<<1;
    }//把所有数字的二进制表示的每一位都加起来
    int result=0;
    for(int i=0;i<32;i++)
    {
        result=result<<1;
        result+=bitSum[i]%3;//按位构造出这个数
    }
    return result;
}