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

例:在{1 2 3 4 5 6 1 2 3 4}找出5和6

方法二:

设计思想:
    1.分组原理
    (1)将所有数字进行异或,相同数字异或为零,所以只会剩5^6,即为异或的结果xor_result
    (2)异或的结果xor_result按位与1,找出xor_result的二进制是从第几位开始有数字1
    (3)根据求出的1所在位置进行分组
     例如:{1,2,3,4,5,6,1,2,3,4}中,xor_result=3,二进制为011,那么可以从第0位或者第1位作为分组标准进行分组
     第0位:第一组:1,3,5,1,3    第二组:2,4,6,2,4
     第1位:第一组:2,3,6,2,3    第二组:1,4,5,1,4
    2.分组方式
    (1)将数组中的元素与xor_result相与,把相与为0和1的数字放在两个组中
    (2)对分别对两个组的元素再次异或,异或的结果就是只出现一次的数字
    即:假设按照第0位分组
     第一组:1^3^5^1^3=5
     第二组:2^4^6^2^4=6
    这样就能求出只出现一次的数字

优点与不足:

时间复杂度O(n),效率比方法一高

只能算出存在两个只出现一次的数字

方法一:

设计思想:

    设计两层循环遍历数组中的每一个元素。

    在内层循环中再次遍历数组,检查是否存在与当前元素相等的其他元素。

    如果存在相同元素,跳出内层循环,返回外循环继续检查下一个元素。如果不存在,那么说明当前元素只出现了一次,打印该这个元素,并将标志位 flag 设置为1。

优点与不足:

数组中存在0个、1个或多个只出现一次的数字可以被找到/提示

时间复杂度O(n^2)

void find_dog(int arr[], int length)
{
	int i = 0;
	int xor_result = 0;
	int tmp = 0;
	int num1 = 0;
	int num2 = 0;
	for ( i = 0; i < length; i++)
	{
		xor_result ^= arr[i];
	}
	for ( i = 0; i < 32; i++)
	{
		if (((xor_result >> i) & 1) == 1)
		{
			tmp = i;
			break;
		}
	}
	for ( i = 0; i < length; i++)
	{
		if (((arr[i] >> tmp) & 1) == 1)
		{
			num1 ^= arr[i];
		}
		else
		{
			num2 ^= arr[i];
		}
	}
	printf("%d %d", num1, num2);

	方法一
	//int i = 0;
	//int j = 0;
	//int flag = 0;//判断是否存在只出现一次的情况,0不存在,1存在
	//for ( i = 0; i < length ; i++)
	//{
	//	for ( j = 0; j < length; j++)
	//	{
	//		
	//		if (i != j && arr[i] == arr[j])
	//			break;
	//	}
	//	if (j == length)
	//	{
	//		flag = 1;
	//		printf("%d\n", arr[i]);
	//	}
	//}
	//if (0 == flag)
	//{
	//	printf("不存在只出现一次的数字!\n");
	//}
}
int main()
{
	int arr[] = { 1,2,3,4,5,6,1,2,3,4 };
	int length = sizeof(arr) / sizeof(arr[0]);
	find_dog(arr, length);
	return 0;
}

你可能感兴趣的:(算法,数据结构,c语言,开发语言,排序算法)