zoukankan      html  css  js  c++  java
  • 找出数组中唯一的重复元素

    题目:

    1-N放在含有N个元素的数组中(N=1001),只有唯一的一个元素值重复,其它均只出现一次.每个数组元素只能访问一次,设计一个算法,将它找出来;不用辅助存储空间,能否设计一个算法实现?

    (1)   方法一:(当N为比较大时警惕溢出)

    将1001个元素相加减去1,2,3,……1000数列的和,得到的差即为重复的元素。

      int   Find(int*   a)  

      {  

      int   i;

      for  (i = 0;i<=1000;i++)    

                    a[1000]   +=   a[i];    

      a[1000]   -=   (i*(i-1))/2       //i的值为1001  

      return   a[1000];  

      }

    (2)   方法二:

    数组取值操作可以看做一个特殊的函数f:D→R,定义域为下标值0~1000,值域为1到1000.如果对任意一个数 i,我们把f(i)叫做它的后继,i叫f(i)的前驱。0只有后继没有前驱,其他数字既有后继也有前驱,重复的那个数字有两个前驱,我们将利用这些特征。

    规律:从0开始画一个箭头指向它的后继,从它的后继继续指向后继的后继,这样,必然会有一个节点指向之前已经出现过的数,即为重复的数。

     

    利用下标与单元中所存储的内容之间的特殊关系,进行遍历访问单元,一旦访问过的单元赋予一个标记,利用标记作为发现重复数字的关键。代码如下:

    void FindRepeat(int array[], int length)

    {

        int index = 0;

        while ( true )

        {

           if ( array[index]<0 )

               break;

           array[index] *= -1; //访问过,变成相反数

           index=array[index]*(-1);

        }

     

        cout<<"The repeat number is "<< -array[index] <<endl;

    }

    (3)   方法三

    同样考虑下标与内容的关系,不过不用标记,而用两个速度不同的过程来访问。Slow每次前进一步,fast每次前进两步。在有环结构中,它们总会相遇。

    void FindRepeat(int array[], int length)

    {

        int slow=fast= 0;

        while ( true ) {

           slow = array[slow];

                  fast = array[array[fast]];

                  if( slow == fast )

                         break;

    }

    fast = 0;

    while( true) {

          slow= array[slow];

    fast =array[fast];

    if( slow == fast )

                         break;

    }

        cout<<"The repeat number is "<< array[slowendl;

    }

    (4)   方法四:异或操作

    数组a[N]中的N个数异或结果与1至N-1异或的结果再做异或,得到的值即为所求。

    • 设重复数为A,其余N-2个数异或结果为B。
    • N个数异或结果为A^A^B
    • 1至N-1异或结果为A^B
    • 由于异或满足交换律和结合律,且X^X = 0 0^X = X;
    • 则有
    • (A^B)^(A^A^B)=A^B^B=A

    void FindRepeat(int array[], int length)

    {

        int result = 0;

           for(int i=1;i<=1000;i++)

                  result ^=  i;

           for(int i=0;i<=1000;i++)

                  result ^=  array[i];

     

        cout << result << endl;

    }

     
     
  • 相关阅读:
    将来要干啥
    选新技术考虑点
    hdfs 创建一个新用户
    linux下实现mysql数据库定时备份
    PostgreSQL的安装和卸载,远程连接
    PostgreSQL语法
    【NiFi系列】1-基本介绍
    大数据相关资源网址
    MySQL主从复制配置
    MySQL设置免密登录
  • 原文地址:https://www.cnblogs.com/yxzfscg/p/4781929.html
Copyright © 2011-2022 走看看