寻找单身狗

目录

一、寻找一个单身狗

1.题目描述

2.思路解析

3.代码实现

二、寻找两个单身狗

1.题目描述

2.思路解析

3.代码实现


一、寻找一个单身狗

1.题目描述

一个数组中只有一个数字只出现一次,其他所有数字都出现了两次,请找出这一个只出现一次的数字。

2.思路解析

首先面对此类问题,我们首先想到的是用循环的方式一个一个找出来,并记录其出现的次数,从而找出只出现一次的数字。但今天我们有更巧妙的办法!———异或

异或^——相同为0,相异为1。我们利用异或的此性质,出现两次的数字异或为0,那么将所有的数字异或的结果岂不就是出现一次的数字吗!单身狗不就找到了!!!

3.代码实现

#include<stdio.h>

int Find_dog(int arr[], int n)
{
	int a = 0;
	int i = 0;
	for (i = 0;i < n;i++)
	{
		a ^= arr[i];
	}
	return a;
}

int main()
{
	int arr[] = { 1,2,3,1,2 };
	int num = Find_dog(arr, 5);
	printf("单身狗为%d\n", num);
	return 0;
}

运行结果:

单身狗为3

二、寻找两个单身狗

1.题目描述

一个数组中有两个数字出现一次,其他所有数字都出现了两次,请找出这两个只出现一次的数字。

2.思路解析

前面我们用异或的方式找到了一个单身狗,那我们能否也用异或的方式找到两只单身狗呢? 

答案是可以的!!但是如果我们像前面一样将全部数字异或,得到的是两个单独的数字的异或值,那好像得不到我们的结果,但是如果我们将这一组数字分为两组呢,再分别异或,那不就得到了嘛。 

3.代码实现

我们来理一理思路啊,以这组数据为例

{1,2,3,4,5,1,2,3,4,7}

首先我们要将这组数据分为两组,如何将两只单身狗放在不同的组里呢?将5和7异或,得到的值的二进制位肯定至少有一位为1,相同为0,相异为1,所以5和7在此二进制的位置必然是一个为0一个为1,那我们就将所有数字此二进制位为0的分为一组,为1的分为一组,再分别异或,单身狗就找到了。

#include<stdio.h>


int main()
{
	int arr[] = { 1,2,3,4,5,1,2,3,4,7 };
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int ret = 0;
	for (i = 0;i < sz;i++)
	{
		//所有值异或,其实就是5与7的异或值
		ret ^= arr[i];
	}
	//找到异或值二进制位为1的位置,将0分为一组,1为一组
	//并找到ret第几位为1
	int pos = 0;
	for (i = 0;i < 32;i++)
	{
		if (((ret >> i) & 1) == 1)
		{
			pos = i;//第pos位为1
			break;//找到之后立马跳出来
		}
	}
	//开始分组,arr[i]的pos位为1为一组
	int num1 = 0;//放1
	int num2 = 0;//放0
	for (i = 0;i < sz;i++)
	{
		if (((arr[i] >> pos) & 1) == 1)
		{
			num1 ^= arr[i];
		}
		else
		{
			num2 ^= arr[i];
		}
	}
	printf("%d %d", num1, num2);
	return 0;
}

运行结果 :

 5 7

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值