位运算

// 数组中数字出现的次数:数组中只出现一次的两个数字,其他数字都出现两次(位运算特点:位异或exclusiveOR(^), 位与(&))
// 其他解法:使用排序,然后二分查找只出现一次的数字,时间O(n log n),
// 使用哈希表存储每个数字出现的次数,时间O(n),空间O(n)
int FindFirstBit1(int number){
    int indexBit = 0;
    while ((number & 1 == 0) && (indexBit < 8 * sizeof(int))){
        number = number >> 1;
        indexBit++;
    }
    return indexBit;
}
bool isBit1(int number, int indexBit){
    number = number >> indexBit;
    return (number & 1);
}
bool g_bInvalid = false;
void FindNumsAppearOnce(int data[], int length, int* num1, int* num2){
    g_bInvalid = false;
    if (data == nullptr || length < 2){
        g_bInvalid = true;
        return;
    }
    int result = 0;
    for (int i = 0; i < length; ++i){
        result ^= data[i];
    }
    *num1 = *num2 = 0;
    int indexBit1 = FindFirstBit1(result);
    for (int i = 0; i < length; ++i){
        if (isBit1(data[i], indexBit1))
            *num1 ^= data[i];
        else
            *num2 ^= data[i];
    }

}
// 数组中只出现一次的一个数字,其他数字都出现三次:按位求和(长度32的辅助数组),出现三次的数字和能被3整除,时间复杂度O(n), 空间复杂度O(1)
int FindNumAppearOnce(int* data, unsigned int length){
    g_bInvalid = false;
    if (data == nullptr || length < 4){
        g_bInvalid = true;
        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 = data[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;
}
原文地址:https://www.cnblogs.com/songdanzju/p/7441958.html