劍指offer演算法題(二)陣列中重複的數字
阿新 • • 發佈:2019-02-05
劍指offer演算法題2
陣列中重複的數字
題目描述
在一個長度為n的數組裡的所有數字都在0到n-1的範圍內。 陣列中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出陣列中任意一個重複的數字。 例如,如果輸入長度為7的陣列{2,3,1,0,2,5,3},那麼對應的輸出是第一個重複的數字2。
解題思路1:
由於所有數字都在 0~n-1 之間,因此,當一個數字被訪問過後,可以設定對應位上的數 + n,之後再遇到相同的數時,會發現對應位上的數已經大於等於n了,那麼直接返回這個數即可。
程式碼實現:
class Solution {
public:
bool duplicate(int numbers[], int length, int* duplication) {
for(int i=0;i<length;i++){
int j=numbers[i]%length;
numbers[j]+=length;
if(numbers[j]>=(2*length)){
*duplication = numbers[j]%length;
return true ;
}
}
return false;
}
};
優點:演算法複雜度低:時間演算法複雜度 ,不需要額外空間。
缺點:可能出現溢位情況,對原陣列進行了修改。
解題思路2:
使用長度為n的記錄陣列 ,初始值設為0, 遍歷原陣列,每個數字都在記錄的陣列上+1,若記錄陣列上的該數字已經等於1,返回該數。
程式碼實現:
class Solution {
public:
bool duplicate(int numbers[], int length, int* duplication) {
int temp[length];
memset(temp, 0, sizeof(temp));
// 區域性陣列沒有預設值,如果宣告的時候不定義,則會出現隨機數。
for(int i=0;i<length;i++){
temp[numbers[i]]++;
if(temp[numbers[i]] >1){
*duplication = numbers[i];
return true;
}
}
return false;
}
};
優點:時間演算法複雜度 ,不改變原陣列。
缺點:空間複雜度高,需要 。
解題思路3
從頭到位掃描陣列,當掃描到下標為i的數字m時,如果是,則掃描下一個數字;如果不是,則那它和第m個數字比較:如果相等,就返回這個重複的數字,如果不相等,就把第i個數字和第m個數字交換。
例子:
{2,3,1,0,2,5,3}
第0個和第2個比較,交換
{1,3,2,0,2,5,3}
第0個和第1個比較,交換
{3,1,2,0,2,5,3}
第0個和第3個比較,交換
{0,1,2,3,2,5,3}
第0個是0,第1個是1,第2個是2,第3個是3
第4個是2,第2個也是2,找到重複數字,返回
程式碼實現:
class Solution {
public:
bool duplicate(int numbers[], int length, int* duplication) {
if(numbers == nullptr || length <= 0)
return false;
for(int i=0;i<length;i++){
if(numbers[i] < 0 || numbers[i] > length-1)
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;
}
};
優點:演算法複雜度低:時間演算法複雜度 ,不需要額外空間;不會出現溢位情況。
缺點:對原陣列進行了修改。