如何找出唯一成对的数(C/C++)
作者:acDream_
来源:CSDN
原文:https://blog.csdn.net/acDream_/column/info/32487
原文是用Java实现的,自己理解后用C语言实现,记录下来。
Problem:
1-1000这1000个数放在含有1001个元素的数组中,只有唯一的一个元素值重复,其他均只出现一次。设计一个算法,将它找出来,你能否设计一个算法实现?
思路1(最先想到的):
首先也是最暴力的方法就是一个循环嵌套一个循环,一个一个去找
时间复杂度为O(n²)
下面是实现的代码:
1 #include<stdio.h> 2 3 int main() 4 { 5 int a[11]={1,2,3,4,4,5,6,7,8,9}; 6 int i,j; 7 int size=sizeof(a)/sizeof(a[0]); //sizeof(a)得到的是 整型长度4*元素个数 8 for(i=0;i<size;i++) 9 for(j=i+1;j<size;j++) 10 if(a[i]==a[j]) 11 printf("%d\n",a[i]); 12 13 return 0; 14 }
思路2:
另外开辟一个大小为1001的数组arr,遍历原来的数组,原来数组中的数就是arr中的下标,若遇到一个数就将对应arr的下标位置对应的值加一就行。然后遍历arr数组,若遇到下标位置对应的值为2的时候,输出下标就行
时间复杂度为O(n)
下面是实现的代码:
1 #include<stdio.h> 2 3 int main() 4 { 5 int i; 6 int a[11]={1,2,3,4,4,5,6,7,8,9}; 7 int b[11]={0}; 8 int size=sizeof(a)/sizeof(a[0]); 9 for(i=0;i<size;i++) 10 { 11 b[a[i]]++; 12 13 if(b[i]==2) 14 printf("%d\n",i); 15 } 16 return 0; 17 }
思路3:
使用异或来找出唯一成对的数,这种算法的效率应该是最高的了,而且不需要辅助空间
先来说一下异或的规则:
a^a=0
a^0=a
然后我们的思路是将这1001个数全部异或起来,那么就会把相同的数给变成0了,那么怎么办呢?
我们可以再次将该数与1-1000之间的数给异或起来
那么不重复的数都会变成0,而重复的数不会变成0
时间复杂度为O(n)
下面是实现的代码:
1 #include<stdio.h> 2 3 int main() 4 { 5 int i,s1=0,s2=0; 6 int a[11]={1,2,3,4,4,5,6,7,8,9}; 7 int size=sizeof(a)/sizeof(a[0]);//size=11 8 for(i=0;i<size;i++) 9 s1=s1^a[i];//s=5 10 for(i=1;i<size-1;i++) 11 s2=s2^i; 12 13 printf("%d\n",s1^s2); 14 15 return 0; 16 }
s1=(1000个数^) ^ 重复数
s2=1000个数^
s1^s2=(1000个数^) ^ 重复数 ^ (1000个数^) = 0 ^ 重复数 = 重复数
思路4:
数学求和法,因为只有一个数字重复一次,而数又是连续的,根据累加和原理,对数组的所有项求和,然后减去1至N-1的和,即为所求的重复数。
时间复杂度为O(n)。
下面是实现的代码:
1 #include<stdio.h> 2 3 int main() 4 { 5 int i,s1=0,s2=0; 6 int a[11]={1,2,3,4,4,5,6,7,8,9}; 7 int size=sizeof(a)/sizeof(a[0]);//size=11 8 for(i=0;i<size;i++) 9 s1=s1+a[i]; 10 for(i=1;i<size-1;i++) 11 s2=s2+i; 12 13 printf("%d\n",s1-s2); 14 15 return 0; 16 }
1.3 找出落单的数,这样编程就对了
Problem:
一个数组里除了某一个数字外,其他的数字都出现了两次。请写程序找出这个只出现一次的数字。
Hint:
这个问题比上一个问题(如何找出唯一成对的数)简单多了,这里直接异或就行了
实现代码:
1 #include<stdio.h> 2 3 int main() 4 { 5 int i,s=0; 6 int a[11]={1,1,2,3,4,2,3,4,5,6,5}; 7 int size=sizeof(a)/sizeof(a[0]);//size=11 8 for(i=0;i<size;i++) 9 s=s^a[i]; 10 11 printf("%d\n",s); 12 13 return 0; 14 }