タイトルの説明
長さnの配列のすべての数値は、0からn-1の範囲です。配列内のいくつかの数字が繰り返されていますが、繰り返し数がわかりません。各数字が何回繰り返されるかわかりません。配列内で重複する番号を見つけてください。たとえば、長さ7の入力配列が{2,3,1,0,2,5,3}の場合、対応する出力は最初に繰り返される数値2です。
問題解決のアイデア
スキャン配列{2,3,1,0,2,5,3}は、添え字0で始まります。現在の位置の番号がその添え字と等しくない場合は、テーブル内の現在の要素の値と交換されます。
- 初めて、添え字は0、値は2になります。等しくない場合、添え字2の数値1と交換してください{1,3,2,0,2,5,3}
- 2回目は、添え字は0、値は1、等しくない、添え字1の数値3と交換{3,1,2,0,2,5,3}
- 3回目、添え字は0、値は3、等しくない、添え字3の数値0と交換{0,1,2,3,2,5,3}
- 4回目、添え字は0、値は0で、次の{1,2,3,2,5,3}と等しい
- 5回目、添え字は1、値は1、等しい、次の{2,3,2,5,3}を判断します
- 6回目、裾は2、値は2、次の{3,2,5,3}と等しい
- 7回目、添え字は3、値は3、次のセルを判断して、等しい、{2,5,3}
- 8回目、下付き文字は4、値は2、等しくない、下付き文字2の番号と交換、次に下付き文字2の番号は2なので、最初の重複する番号が見つかります
コードの実装
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 == 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;
}
swap(numbers[i],numbers[numbers[i]]);
}
}
return false;
}
};