算法记录(一)
题目:在数组中只有两个奇数次出现的数,其余都是偶数次出现的数,找到这两个数
算法:
我们采用异或来解答这道题,异或有这样两个特性,a^a=0,而0^a=a,所以我们可以知道数组中的所有数互相异或后,最终得到的结果eor=a^b(因为c^c=0),而a和b就是我们要找的这两个数。
那怎么求这两个数呢,这里有一个隐含条件,a!=b(如果a=b则出现次数为偶数,不符合题意)。这时候我们可以将数转换为2进制来看,因为两数不相等的话在二进制中一定至少有一位是不相同的,所以我们可以将数组分为两部分,一部分是某一位为1.一部分是某一位为0,而a和b是一定在不同的部分。随后再次进行异或,异或的结果为eor',偶数次的数异或完eor'等于0,而奇数次的数异或完eor'!=0,那eor'就是a或b中的一个,另一个则通过eor和eor'异或求出。
代码:
void FindOddNum(vector<int> n)
{
int eor = 0;
for (int i = 0; i < n.size(); ++i)
{
eor = eor ^ n[i];
}
int rightOne = eor & (~eor + 1);//求得在二进制中最右边的1,其余的位都为0;
int oneOfA=0;
for (int i = 0; i < n.size(); ++i)
{
if ((n[i] & rightOne) != 0)
oneOfA ^= n[i];
}
cout << "这两个数为:"+to_string(oneOfA)+"和"+to_string(oneOfA^eor) << endl;
}