牛客上的題目,參考劍指offer,轉載自:http://www.cnblogs.com/AndyJee/p/4693099.html
題目:
在一個長度爲n的數組裏的所有數字都在0到n-1的範圍內。 數組中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出數組中任意一個重複的數字。
例如,如果輸入長度爲7的數組{2,3,1,0,2,5,3},那麼對應的輸出是重複的數字2或者3。
思路:
1、排序
將數組排序,然後掃描排序後的數組即可。
時間複雜度:O(nlogn),空間複雜度:O(1)
2、哈希表
從頭到尾掃描數組,每掃描到一個數字,判斷該數字是否在哈希表中,如果該哈希表還沒有這個數字,那麼加入哈希表,如果已經存在,則返回該數字;
時間複雜度:O(n),空間複雜度:O(n)
3、交換
0~n-1正常的排序應該是A[i]=i;因此可以通過交換的方式,將它們都各自放回屬於自己的位置;
從頭到尾掃描數組A,當掃描到下標爲i的數字m時,首先比較這個數字m是不是等於i,
如果是,則繼續掃描下一個數字;
如果不是,則判斷它和A[m]是否相等,如果是,則找到了第一個重複的數字(在下標爲i和m的位置都出現了m);如果不是,則把A[i]和A[m]交換,即把m放回屬於它的位置;
重複上述過程,直至找到一個重複的數字;
時間複雜度:O(n),空間複雜度:O(1)
(將每個數字放到屬於自己的位置最多交換兩次)
代碼:
交換
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
#include
<iostream> using namespace std; bool duplicate( int numbers[], int length, int *
duplication){ if (numbers==NULL
|| length<=1){ duplication=NULL; return false ; } for ( int i=0;i<length;i++){ while (numbers[i]!=i){ if (numbers[i]==numbers[numbers[i]]){ *duplication=numbers[i]; return true ; } int tmp=numbers[i]; numbers[i]=numbers[tmp]; numbers[tmp]=tmp; } } return false ; } int main() { int A[]={2,3,1,0,2,5,3}; int len= sizeof (A)/ sizeof (A[0]); int duplication; cout
<< duplicate(A,len,&duplication) << endl; cout
<< duplication << endl; return 0; } |