找出數組中唯一的重復元素


找出數組中唯一的重復元素※

1-1000放在含有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)   方法四:異或操作

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;

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM