著者: Zhai Tianbao Steven
著作権表示: 著作権は著者に属します。商業的転載の場合は、許可について著者に連絡してください。非商業的な転載の場合は、出典を示してください。
タイトル説明:
長さ n の配列内のすべての数値は、0 から n-1 の範囲内にあります。配列内のいくつかの数値が繰り返されていますが、いくつの数値が繰り返されているのかわかりません。各数字が何回繰り返されるかも不明です。配列内で繰り返される数値を見つけてください。たとえば、入力が長さ 7 の配列 [2,3,1,0,2,5,3] の場合、対応する出力は 2 または 3 になります。不正な入力があった場合は、-1を出力します。
データ範囲: 0≤n≤10000
上級: 時間計算量 O(n)、空間計算量 O(n)
例:
入力:
[2,3,1,0,2,5,3]
戻り値:
2
例証します:
2か3はどちらも正しいです
問題解決のアイデア:
この質問は並べ替えの質問であり、解決するには 4 つの方法があります。
1) 暴力の法則
二重ループの走査、重複する番号を見つけて戻ります。時間計算量 O(n^2)、空間計算量 O(1)。
2) ソートトラバーサル方式
クイックソートを使用して配列をソートし、検索を横断します。時間計算量 O(nlogn)、空間計算量 O(1)。
3) ハッシュテーブル
ハッシュ テーブルを使用して、数値が繰り返されているかどうかを判断します。ハッシュ セットまたはハッシュ マップを使用できます。ハッシュ テーブルのルックアップは O(1) であるため、1 ラウンドで実行するだけで完了します。時間計算量 O(n)、空間計算量 O(n)。
4) 添え字ハッシュ
数値 2 などの配列の添字をハッシュ キーとして使用し、それを配列の添字 2 の位置に置き、元の添字 2 の位置にある数値を元の数値 2 の位置に移動して、交換を完了します。特定の交換が見つかるまで続きます。数値 x と添え字 x の数値が競合し、重複する値が見つかったことを示します。最悪の場合は、重複する数値がなく、すべての添え字が 1 ラウンドにわたって調べられ交換されたことです。 。時間計算量 O(n)、空間計算量 O(1)。
注: この方法を適用する前提は、タイトルに示されている条件のように、数値の範囲が 0 から n-1 までであることです。それ以外の場合は範囲外です。
テストコード:
1) 暴力の法則
class Solution {
public:
// 寻找重复数据
int duplicate(vector<int>& numbers) {
int size= int(numbers.size());
for (int i = 0; i < size; ++i){
for (int j = i + 1; j < size; ++j){
if (numbers[i] == numbers[j])
return numbers[i];
}
}
return -1;
}
};
2) ソートトラバーサル方式
class Solution {
public:
// 寻找重复数据
int duplicate(vector<int>& numbers) {
// 快排
sort(numbers.begin(),numbers.end());
int size = int(numbers.size());
// 寻找重复值
for(int i = 1; i <size; ++i){
if(numbers[i] == numbers[i - 1])
return numbers[i];
}
return -1;
}
};
3) ハッシュテーブル
class Solution {
public:
// 寻找重复数据
int duplicate(vector<int>& numbers) {
// 哈希set
unordered_set<int> us;
int size = int(numbers.size());
for(int i = 0; i < size; ++i){
if(us.count(numbers[i]))
return numbers[i];
else
us.insert(numbers[i]);
}
return -1;
}
};
4) 添え字ハッシュ
class Solution {
public:
// 寻找重复数据
int duplicate(vector<int>& numbers) {
// 下标哈希法
int size = int(numbers.size());
for(int i = 0; i < size;){
if(numbers[i]==i)
i++;
else{
if(numbers[numbers[i]] == numbers[i])
return numbers[i];
else{
swap(numbers[numbers[i]], numbers[i]);
}
}
}
return -1;
}
};