CodingInterview-数组中重复的数字

首先想了一个比较简单的思路,利用了一个简单的哈希表来解决问题,时间空间复杂度都为 O(n)。

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
class Solution {
public:
// Parameters:
// numbers: an array of integers
// length: the length of array numbers
// duplication: (Output) the duplicated number in the array number
// Return value: true if the input is valid, and there are some duplications in the array number
// otherwise false
bool duplicate(int numbers[], int length, int* duplication) {
if(numbers==NULL || length<=0) return false;
for(int i=0;i<length;i++){
if(numbers[i]<0 || numbers[i]>=length) return false;
}
int times[length];
for(int i=0;i<length;i++) times[i]=0;
for(int i=0;i<length;i++) times[numbers[i]]++;
*duplication=-1;
for(int i=0;i<length;i++){
if(times[i]>1){
*duplication=i;
return true;
}
}
return false;
}
};

使用数组本身作为哈希表,让空间复杂度减少为 O(1)。为了让哈希不与原数字冲突,每遇到一次相同的,就加 length。

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
class Solution {
public:
// Parameters:
// numbers: an array of integers
// length: the length of array numbers
// duplication: (Output) the duplicated number in the array number
// Return value: true if the input is valid, and there are some duplications in the array number
// otherwise false
bool duplicate(int numbers[], int length, int* duplication) {
if(numbers==NULL || length<=0) return false;
for(int i=0;i<length;i++){
if(numbers[i]<0 || numbers[i]>=length) return false;
}
for(int i=0;i<length;i++){
numbers[numbers[i]%length]+=length;
}
for(int i=0;i<length;i++){
if(numbers[i]/length>1){
*duplication=i;
return true;
}
}
return false;
}
};

看了书以后,发现还有一个有意思的思路,是通过交换把数字放在本来应该有的位置来发现重复的数字。

首先通过不断的交换,尽量把和索引相同的数字放在索引所在的空间中,然后一旦发现后面的数字和索引中的数字(此时已经和索引相同了)相同,那么就说明发现了重复。

但是感觉这个有一些问题,如果再相应的位置上没有和索引相同的数字,就会陷入死循环,好在测试用例中没有这样的 case。

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
class Solution {
public:
// Parameters:
// numbers: an array of integers
// length: the length of array numbers
// duplication: (Output) the duplicated number in the array number
// Return value: true if the input is valid, and there are some duplications in the array number
// otherwise false
bool duplicate(int numbers[], int length, int* duplication) {
if(numbers==NULL || length<=0) return false;
for(int i=0;i<length;i++){
if(numbers[i]<0 || numbers[i]>=length) return false;
}
for(int i=0;i<length;i++){
while(i!=numbers[i]){
if(numbers[i]==numbers[numbers[i]]){
*duplication=numbers[i];
return true;
}
int t=numbers[i];
numbers[i]=numbers[t];
numbers[t]=t;
}
}
return false;
}
};