Sword はオファーを参照します (C++)-JZ3: 配列内の繰り返し番号 (アルゴリズム - ソート)

著者: 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;
    }
};

おすすめ

転載: blog.csdn.net/zhaitianbao/article/details/131239966