• 如何找出唯一成对的数(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
    ",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
    ",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
    ",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
    ",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
    ",s);
    12 
    13     return 0;
    14 }
  • 相关阅读:
    golang recover
    golang sort
    golang matrix
    golang encoding/json
    go package的理解
    golang beego cache
    git操作
    阿里云图标使用
    Stylus的使用
    vue-preview的使用
  • 原文地址:https://www.cnblogs.com/kaml8/p/10356179.html
Copyright © 2020-2023  润新知