所属专栏:经典算法题❤️
🚀 >博主首页:初阳785❤️
🚀 >代码托管:chuyang785❤️
🚀 >感谢大家的支持,您的点赞和关注是对我最大的支持!!!❤️
🚀 >博主也会更加的努力,创作出更优质的博文!!❤️
🚀 >关注我,关注我,关注我,重要的事情说三遍!!!!!!!!❤️
1.初级单身狗
1.1题目描述
一个数组中只有一个数字是出现一次,其他所有数字都出现了一次。
例如:
有数组的元素是:1,2,3,4,5,1,2,3,4
只有5出现一次,找出这个数。
1.2解题思路
-
仔细思考我们发现,相同的两个数发生按位异或后就会等于0,就相当于消消乐一样,二0异或任何数都是本身,通过这个特性我们就很快可以得到解题思路了。
-
首先第一步,我们初始化一个变量int x=0;我们用x按位异或数组中每个元素
然后,我们将得到的结果在赋值给x,
最后等到这个数组遍历完后,最终x的值就是单身狗。 -
但是这个时候就有人会疑问,我们遍历数组的时候,元素是随机的,没办法得到相邻的相同的两个数之间按位异或然后消除掉啊。拿着怎么办。其实这个不必担心,因为这个按位异或你可想象成是多个数进行相乘,二乘法是符号交换律的,同样的按位异或也符合交换律这一特点,所有无论这两个相同的数位置在哪里,只要他们相同就一定会相互消除。
1.3代码实现
#include <stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,1,2,3,4};
int x = 0;
int i = 0;
for (i = 0; i < 7; i++)
{
x ^= arr[i];
}
printf("%d", x);
return 0;
}
2.升级单身狗
2.1题目描述
一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。
编写一个函数找出这两个只出现一次的数字。
例如:
有数组的元素是:1,2,3,4,5,1,2,3,4,6
只有5和6只出现1次,要找出5和6.
2.2解题思路
如果我们接着上一题的思路的话,我们得到是两个单身狗异或后的结果。于是我们承接着上一题的思路,从这两个单身狗异或后的到的结果思考。我们知道,相同的两个数他们的二进制位都是对应相同的,要么是1要么是0,于是我们就可有从这一特点出发。既然我们无法通过直接异或得到结果,我们就想办法把这两个单身狗分别分成两派,把他转换成你只有一个单身狗的情况,就按照0/1分配,这个时候这两个单身狗异或后得到的结果派上用场了。异或的特点就是相同为0,相异为1,如果我们把异或后得到的结果通过右移并且按位与上1,如果这个结果是1的话,那么就说明右移的位数就是这两个单身狗二进制位不同的地方一个是1另一个是0,然后我们既然右移的位数,通过0和1把他们区分成两队,这个时候就转换成了只有一个单身狗的情况了。
2.3代码实现
#include <stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,1,2,3,4,6 };
int x = 0;
int i = 0;
//先找到两个单身狗异或之后得到的结果。
for (i = 0; i < 10; i++)
{
x ^= arr[i];
}
//通过异或之后的结果找到第一个不同的二进制位
int count = 0;
while (((x >> count)&1)==0)
{
count++;
}
int a = 0;
int b = 0;
//通过右移,按照不同的位分成两类,转换成一个单生狗的情况
for (i = 0; i < 10; i++)
{
if (((arr[i] >> count)&1) == 0)
{
a^=arr[i];
}
else
{
b ^= arr[i];
}
}
printf("%d %d", a, b);
return 0;
}