本文首發于我的個人部落格: 尾尾部落
題目描述
在一個長度為n的數組裡的所有數字都在0到n-1的範圍内。 數組中某些數字是重複的,但不知道有幾個數字是重複的。也不知道每個數字重複幾次。請找出數組中任意一個重複的數字。 例如,如果輸入長度為7的數組{2,3,1,0,2,5,3},那麼對應的輸出是第一個重複的數字2。
解題思路
最簡單的就是用一個數組或者哈希表來存儲已經周遊過的數字,但是這樣需要開辟額外的空間。
如果題目要求不能開辟額外的空間,那我們可以用如下的方法:
因為數組中的數字都在0~n-1的範圍内,是以,如果數組中沒有重複的數,那當數組排序後,數字i将出現在下标為i的位置。現在我們重排這個數組,從頭到尾掃描每個數字,當掃描到下标為i的數字時,首先比較這個數字(記為m)是不是等于i。如果是,則接着掃描下一個數字;如果不是,則再拿它和m 位置上的數字進行比較,如果它們相等,就找到了一個重複的數字(該數字在下标為i和m的位置都出現了),傳回true;如果它和m位置上的數字不相等,就把第i個數字和第m個數字交換,把m放到屬于它的位置。接下來再繼續循環,直到最後還沒找到認為沒找到重複元素,傳回false。
參考代碼
public class Solution {
// Parameters:
// numbers: an array of integers
// length: the length of array numbers
// duplication: (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation;
// Here duplication like pointor in C/C++, duplication[0] equal *duplication in C/C++
// 這裡要特别注意~傳回任意重複的一個,指派duplication[0]
// Return value: true if the input is valid, and there are some duplications in the array number
// otherwise false
public boolean duplicate(int numbers[],int length,int [] duplication) {
if(length == 0)
return false;
for(int i = 0; i < length; i++){
while(i != numbers[i]){
if(numbers[i] == numbers[numbers[i]]){
duplication[0] = numbers[i];
return true;
}else{
int temp = numbers[numbers[i]];
numbers[numbers[i]] = numbers[i];
numbers[i] = temp;
}
}
}
return false;
}
}