刷题之:找数组中只出现一次的两个数

刷题之:找数组中只出现一次的两个数,第1张

刷题之:找数组中只出现一次的两个

目录

题目:

函数实现思路

分离两个待查找的数

定位二进制为1的位数

全部代码实现


示例:

int arr[] = { 1,1,2,2,3,3,4,5,5,6,7,7,8,8,9,9 };

题目:


在数据成对出现的数组中又两个数值只出现了一次,将这两个数值找出来。

思路

如上面的示例,我们需要将4,6这两个只出现一次的数值找到。明显过程较为复杂,我们采用函数包装。

函数设计

我们需要清楚函数的参数,返回类型是什么?

需要处理的是一个数组,采用指针/数组传参,传数组的元素个数;我们需要返回两个数,所以需要返回一个数组,即一个地址,采用整形指针类型。

int* singleNumber(int* arr, int numsSize)

函数实现思路


异或解法:我们知道,使用异或解决只出现一个一次出现的数时,是十分简便的,所以只要将找两个出现一次的数值,转化为找一个出现一次的数值就好解决了。由此可以想到,需要将数据分为两个部分,两个出现一次的数值分别发布在两边,就转化为了求解两个找出现一次的数值的问题了。

分离两个待查找的数


如何分离呢?

我们需要找到这两个数的不同之处,使用异或可以将这两个数区分开来。

 那么我们就可以根据这一特性将其分开,我们选取异或(^)后的二进制序列任意一位为1的位数。只要数组中元素对应的这二进制位为1的数值就分到一组,为0的分到另外一组。这里可以分析一下,最后分到两组的元素是怎么样的呢?

(有一个出现一次的数值,其余的都是成对出现的)

为什么是成对出现的呢?

刚刚提到有一位二进制位数相同的进入同一组,那么数值相同二进制序列也就相同,也就会进入同一组,只有两个只出现一次的数值才会被分开分别进入两组。

定位二进制为1的位数


首先定位一个二进制位为1的位数m

    int x = 0;
	int i = 0;
	for (i = 0; i < numsSize; i++)
	{
		x ^= arr[i];//异或
	}
	int m = 0;
	//定位x二进制序列为1的位数
	for (i = 0; i < 32; i++)
	{
		if ((x >> i & 1) == 1)
		{
			m = i;
			break;
		}
	}

再将其分开

//将出现一次的两个数分开
	int x1 = 0;
	int x2 = 0;
	for (i = 0; i < numsSize; i++)
	{
		if ((arr[i] >> m & 1) == 1)
		{
			x1 ^= arr[i];//只有一个数值出现一次其余成对出现的全部被异或完了
		}
		else
		{
			x2 ^= arr[i];//只有一个数值出现一次其余成对出现的全部被异或完了
		}
	}

最后返回值就可以了

int* a = (int*)malloc(sizeof(int)*2);
	a[0] = x1;
	a[1] = x2;
	
	return a;

全部代码实现


#include 
#include 

int* singleNumber(int* arr, int numsSize)
{
	int x = 0;
	int i = 0;
	for (i = 0; i < numsSize; i++)
	{
		x ^= arr[i];//异或
	}
	int m = 0;
	//定位x二进制序列为1的位数
	for (i = 0; i < 32; i++)
	{
		if ((x >> i & 1) == 1)
		{
			m = i;
			break;
		}
	}
	
	//将出现一次的两个数分开
	int x1 = 0;
	int x2 = 0;
	for (i = 0; i < numsSize; i++)
	{
		if ((arr[i] >> m & 1) == 1)
		{
			x1 ^= arr[i];
		}
		else
		{
			x2 ^= arr[i];
		}
	}
	int* a = (int*)malloc(sizeof(int)*2);
	a[0] = x1;
	a[1] = x2;
	
	return a;
}
int main()
{
	int arr[] = { 1,1,2,2,3,3,4,5,5,6,7,7,8,8,9,9 };
	int len = sizeof(arr) / sizeof(int);
	int i = 0;
	int* pa = singleNumber(arr, len);
	for (i = 0; i < 2; i++)
	{
		printf("%d ",pa[i]);
	}
	free(pa);
	pa = NULL;

	return 0;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5713559.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存