首先这个题目一般有三种变体:
1)其他元素均出现两次,只有一个数字仅出现一次;------ 将所有数字元素进行异或操作即可得到最终结果
2)其他元素均出现两次,只有2个元素仅出现一次;----- 思路:这两个数字肯定不同,两者进行异或操作结果肯定有一位为1,根据这位的不同可以将数组分为两类,则可以分别在两类中每个元素都进行异或操作,来找到两个元素只出现一次的元素;
class Solution {
public:
void FindNumsAppearOnce(vector<int> data,int* num1,int *num2) {
int len=data.size();
if(len<=1)
{ *num1=0;*num2=0;return;}
int sum=0;
for(int i=0;i<len;++i)
{
sum=sum^data[i];
}
unsigned int n=1;
while((sum&n) == 0)
{
n=n<<1;
}
int n1=0,n2=0;
for(int i=0;i<len;++i)
{
if((data[i]&n)==0)
{
n1=n1^data[i];
}
else
{
n2=n2^data[i];
}
}
*num1=n1;*num2=n2;
}
};
3)其他数字出现三次,仅X出现一次,找出X;------思路:如果数字中木有X,辣么数组中所有的数组都出现了3次,在二进制上,每位上1的个数肯定也能被3整除;所以可以对整个数组在每位上进行求和,就可以得到X的二进制表示中每位上是1还是0了;
void main()
{
int a[] = { 3, 9,9,3,3,9,4, 4, 80, 4 };
int len = sizeof(a) / sizeof(a[0]);
int* bits = new int[32];
memset(bits, 0, sizeof(int)* 32);
for (int i = 0; i < len; ++i)
for (int j = 0; j < 32; ++j)
{
bits[j] += ((a[i] & (1 << j)) == 0 ? 0 : 1);
}
int result = 0;
for (int i = 0; i < 32; ++i)
{
result += (bits[i] % 3)*pow(2, i);
}
cout << result << endl;
}