int RepeatNum(int *Array, int N) { int i; int TempSum1 = 0, TempSum2 = 0; for(i = 0;i < N;i++) { TempSum1 = i + 1; TempSum2+ = Array[i]; } return N-(TempSum1 - TempSum2) ; }
解法二:網上將此種解法稱之爲標誌數組法。該解法的核心思想是:申請一個數組長度爲N-1的字符串數組Help[N-1],並將該數組的各項均初始爲’0‘,然後從頭開始遍歷數組A[N],取A[i]的值,並將在Help數組上相應的位置,即Help[A[i]-1] = '1',如果該位置已經是置過'1'的話,那麼該數就是那個重複的數。該方法的實現代碼如下:
int RepeatNum(int *Array, int N) { int i; char Help[N-1]; for(i = 0;i < N-1;i++) { Help[i] = '0'; } for(i = 0;i < N;i++) { if(Help[A[i]-1] == '1') return A[i]; else Help[A[i-1]] = '1'; } }
解法三:固定偏移標誌法。這種方法是我在網上找的,該解法的核心思想是:利用A[N]本身中值和下標的關係來做標記,處理完成後再清楚標記即可。對於數組A[N],最大的數是N-1,若A[i] = M在某處出現時,將A[M]加一次N,做標記,當某處A[i] = K再次成立時,查看A[K],就可以知道K已經出現過。A[i]在程序中最大的時候是N-1+N=2*N-1,這不是超出範圍了嗎?不要緊,我們可將它作爲一個限制條件。實現代碼如下:
int RepeatNum(int *Array,int N) { int temp=0; for(int i=0; i<N; i++) { if(Array[i] >= N) temp = Array[i]-N; // 該值重複了,因爲曾經加過一次了 else temp = Array[i]; if(Array[temp] < N) { Array[temp]+ = N; //做上標記 } else { return temp; //有重複; } } return -1;//無重複 }
好了,對於情況一的解法暫時就是這些。如果您還有更好的解法請提出來,分享一下。接下來我們開始討論情況二所對應的相關解法。
int RepeatNum(int *Array,int N) { int i, j; for(i = 0;i < N - 1;i++) { for(j = i + 1;j <= N - 1; j++) { if(Array[i] == Array[j]) { return Array[j]; } } } }
解法二:由於該數組中的元素很有可能是無序的,所以當你拿到這個問題時,解法一通常是先想到的。但是由於解法一的效率不是很好(時間複雜度爲O(N*N)),那我們怎麼提高呢?OK,我們來看看解法二。解法二的思想很簡單,就是先對數組做一次排序,讓數組成爲有序的,即從小到大或者從大到小。做排序的話,可供我們選擇的優秀的排序算法有很多,比如快速排序、堆排序、歸併排序等,而且這幾種排序算法的時間複雜度都是O(N*LgN),你可以任選一種。排序完成之後,數組A[N]變成有序數組,那麼從這個有序數組中找出那個重複的數,問題就好解決了,只需做一次循環就可以解決。具體做法是:從頭開始遍歷這個有序數組,當前一個數和後一個數相等時就是我們要找的那個重複的數,不相等時只需i++,比較一下組數,知道找出那個重複的數。對於此解法,時間複雜度爲O(N*LgN+N)。實現代碼如下:
int RepeatNum(int *OrderArray,int N) { int i; for(i = 0;i < N;i++) { if(OrderArray[i] == OrderArray[i+1]) return OrderArray[i]; } }
上述兩種解法,我們應該很容易就能夠做到。那麼還有沒有更好的方法呢?當然有,接下來我們就開始介紹第三種方法。
解法三:我認爲可以用哈希算法來解決這個問題。利用哈希算法,可以建立一種鍵值與真實值之間的對應關係。每一個真實值只有一個鍵值,但是每一個鍵值可以對應多個真實值,這樣可以再數組中很快的找到我們想要的數,而且利用哈希算法可以對該問題在時間複雜度上做出很好的優化。關於哈希算法及其原理,我在網上找了一些資料分享一下。
哈希算法原理:http://wenwen.soso.com/z/q181569235.htm
哈希算法:http://baike.soso.com/ShowLemma.e?sp=l7892037&ch=w.search.baike.unelite
著名的哈希算法:http://blog.csdn.net/longronglin/article/details/1782678
暴雪的哈希算法:http://opaque.blogbus.com/logs/30017835.html
OK,以上就是對數組中找重複數的幾種解法。不過我相信對於這個問題的解法絕不止上述幾個,肯定還有更好的解法,歡迎大家分享,共同交流。