1-1000放在含有1001個元素的數組中,只有唯一的一個元素值重複,其它均只出現 一次。每個數組元素只能訪問一次,設計一個演算法,將它找出來;不用輔助儲存空 間,能否設計一個演算法實現?將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];
}利用下標與單元中所儲存的內容之間的特殊關係,進行遍曆訪問單元,一旦訪問過的單元賦予一個標記,利用標記作為發現重複數位關鍵。代碼如下:void FindRepeat(int array[], int length){ int index=array[length-1]-1; while ( true ) { if ( array[index]<0 ) break; array[index]*=-1; index=array[index]*(-1)-1; } cout<<"The repeat number is "<<index+1<<endl;}此種方法不非常的不錯,而且它具有可擴充性。在罈子上有人提出:對於一個既定的自然數 N ,有一個 N + M 個元素的數組,其中存放了小於等於 N 的所有自然數,求重複出現的自然數序列{X} 。 對於這個擴充需要,自己在A_B_C_ABC(黃瓜兒才起蒂蒂)的演算法的基礎上得到了自己的演算法代碼:按照A_B_C_ABC(黃瓜兒才起蒂蒂)的演算法,易經標記過的單元在後面一定不會再訪問到,除非它是重複的數字,也就是說只要每次將重複數字中的一個改為靠近N+M的自然數,讓遍曆能訪問到數組後面的單元,就能將整個數組遍曆完。代碼:*/void FindRepeat(int array[], int length, int num){ int index=array[length-1]-1; cout<<"The repeat number is "; while ( true ) { if ( array[index]<0 ) { num--; array[index]=length-num; cout<<index+1<<'t'; } if ( num==0 ) { cout<<endl; return; } array[index]*=-1; index=array[index]*(-1)-1; }}