❝
涓滴之水终可以磨损大石,不是由于它力量强大,而是由于昼夜不舍的滴坠。——贝多芬
❞
配列内の繰り返し番号を検索します
タイトル説明
長さnの配列内のすべての数値は、0からn-1の範囲です。配列内のいくつかの数字が繰り返されていますが、繰り返される数字の数も、各数字が繰り返される回数もわかりません。配列内で重複する番号を見つけてください。たとえば、入力長が7配列{2、3、1、0、2、5、3}の場合、対応する出力は繰り返し番号2または3です。
解決
解決策1:
並べ替えた後、繰り返しスキャンして繰り返しがあるかどうかを判断します。時間計算量はO(n²)です。
解決策2:
ハッシュテーブルを使用して配列を走査します。ハッシュテーブルにそのような要素がない場合は、ハッシュテーブルに格納します。それ以外の場合は、重複する要素を返します。時間計算量はO(n)であり、空間計算量はO(n)です。
解決策3
長さはnで、要素の値の範囲もnです。繰り返される要素がない場合、配列の各添え字に対応する値は添え字と等しくなります。
下付き文字iの数値nums [i]までスキャンするときに、配列を最初から最後までトラバースします。
- iと等しい場合は、スキャンダウンを続けます。
- iと等しくない場合は、nums [i]番目の数値と比較します。等しい場合は、値が重複していることを意味し、nums [i]を返します。等しくない場合は、i番目の数値をnums [i]番目の数値と交換します。この比較交換プロセスを繰り返します。
このアルゴリズムの時間計算量はO(n)です。これは、位置を決定するために各要素を最大2回交換するだけでよいためです。スペースの複雑さはO(1)です。
/**
* @author bingo
* @since 2018/10/27
*/
public class Solution {
/**
* 查找数组中的重复元素
* @param numbers 数组
* @param length 数组长度
* @param duplication duplication[0]存储重复元素
* @return boolean
*/
public boolean duplicate(int[] numbers, int length, int[] duplication) {
if (numbers == null || length < 1) {
return false;
}
for (int e : numbers) {
if (e >= length) {
return false;
}
}
for (int i = 0; i < length; ++i) {
while (numbers[i] != i) {
if (numbers[i] == numbers[numbers[i]]) {
duplication[0] = numbers[i];
return true;
}
swap(numbers, i, numbers[i]);
}
}
return false;
}
private void swap(int[] numbers, int i, int j) {
int t = numbers[i];
numbers[i] = numbers[j];
numbers[j] = t;
}
}
テストケース
- 長さnの配列には、1つ以上の繰り返し数が含まれます。
- 配列には繰り返し番号は含まれていません。
- 無効なテスト入力ケース(nullポインターを入力します。長さnの配列に0〜n-以外の数値が含まれています)。
私は自分が書いたすべての問題解決策を電子書籍にまとめてgithubに配置し、3日間でgithubランキングのトップになりました!ほぼ5w人がダウンロードして読んだ!入手したい場合は、以下のリンクにアクセスしてください(星を付けるのを忘れないでください)。