找单身狗编程题:一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。 编写一个函数找出这两个只出现一次的数字。

文章目录

  • 一、暴力搜索法
  • 二、位运算法

一、暴力搜索法

void same(int arr[], int len,int* num1,int* num2)
{
	int i, j;
	int flag = 0;// 标记是否找到第一个唯一数字
	for (i = 0; i < len; i++)
	{
		int tmp = 1;
		// 检查 arr[i] 是否在数组中有重复
		for (j = 0; j < len; j++)
		{
			if (i != j && arr[i] == arr[j])
			{
				tmp = 0; // 发现重复,不是唯一
				break;
			}
		}		
		if (tmp == 1)
		{
			if (!flag)
			{
				*num1 = arr[i];// 存储第一个唯一数字
				flag = 1;// 标记已找到第一个
			}
			else
			{
				*num2 = arr[i];// 存储第二个唯一数字
				return;
			}
		}
	}
}
int main()
{
	int arr[] = { 1,2,3,4,5,1,2,3,4,6 };
	int len = sizeof(arr) / sizeof(arr[0]);
	int num1=0, num2=0;
	same(arr, len, &num1, &num2);
	printf("单独出现的两个数为:%d %d\n", num1, num2);
	return 0;
}

注意:

flag 的作用:

flag = 0 表示还没找到第一个唯一数字。

当找到第一个唯一数字时,存储到 *num1,并设置 flag = 1。

当 flag= 1 时,再找到的唯一数字就是第二个,存储到 *num2 并立即 return。

避免 j 越界:

原始代码错误地使用了 arr[j](循环结束后 j = len,导致越界)。

修正后的代码 不会依赖 j 的值,而是继续遍历数组寻找第二个唯一数字。

二、位运算法

void same(int arr[], int len, int* num1, int* num2)
{	//1.整体异或得到5^6的结果tmp
 int tmp = 0;
 for (int i = 0; i < len; i++)
 {
 	tmp ^= arr[i];
 }
 //2.算出tmp的哪一位是1,pos位置记录下来
 int pos;
 for (int i = 0; i < 32; i++)
 {
 	if ((tmp >> i) & 1 == 1)
 	{
 		pos = i;
 		break;
 	}
 }
 //3.再次遍历数组的每个数字看pos位置是不是0或1,分到两个组
 for (int i = 0; i < len; i++)
 {
 	if ((arr[i] >> pos) & 1 == 1)
 		*num1 ^= arr[i];
 	else
 		*num2 ^= arr[i];
 }
}
int main()
{
 int arr[] = { 1,2,3,4,5,1,2,3,4,6 };
 int len = sizeof(arr) / sizeof(arr[0]);
 int num1 = 0, num2 = 0;
 same(arr, len, &num1, &num2);
 printf("单独出现的两个数为:%d %d\n", num1, num2);
 return 0;
}

输出结果:

单独出现的两个数为:5 6

注意:
在 same 函数中初始化 *num1 和 *num2:确保异或操作从 0 开始计算。

你可能感兴趣的:(C语言编程题,算法,数据结构,c语言)