找两只单身狗

C语言找一个数组中数字都是成对出现的,只有两个是只出现一次的。

我首先想到的就是先排序,然后相邻的两个元素相减,结果不为零则是一只单身狗,然后继续循环。但这个方法不满足时间复杂度的要求,其次就是异或。

用异或的方法求解:

1、先用0与数组里的所有元素进行异或,得到一个结果,这个结果就是两个单身狗的异或结果。

2、异或的结果中必定含有1,例:3和4的异或结果为,0111。

       这里解释一下:异或是相异为1,所以两个单身狗异或的结果中为1的位(假设这个是结果中第M位),必定是0和1或1和0的结合,通过区分数组中每个元素的第M位,可以把数组分为两组,这样每组含有一个单身狗,每组进行异或就可以得到数组里面的两个单身狗。

#include<stdio.h>
int main()
{
	int arr[] = { 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	int x = 0;
	for (i = 0; i < sz; i++)
	{
		x ^= arr[i];//出现两次的异或等于0,x最后的结果是3和7异或的结果=0100
	}
	int m = 0;
	while (m<32)//判断x的结果第几位为1
	{
		if (((x >> m) & 1)==1)//右移x,m确定哪一位为1,异或的结果相异为1
		{
			break;
		}
		else
		{
			m++;
		}
	}
	//分组,把数组各个元素右移m位,与1相与,结果为1的为一组,为零分为第二组,
	
	int a = 0;
	int b = 0;
	for (i = 0; i < sz; i++)
	{
		if (((arr[i] >> m) & 1) == 1)
		{
			b ^= arr[i];//为1的一组异或,得到b
		}
		else
		{
		   a^=arr[i];//为0的一组异或,得到a
		}
	}
	printf("%d和%d\n", a, b);                                                                                                                                                                                                                                                                                                                                                                                                
    return 0;
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值