アルゴリズム:O(n)とO(nlog(n))を合計するにはどうすればよいですか?


22

重複を見つけて削除する次のアルゴリズムがあります:

public static int numDuplicatesB(int[] arr) {
    Sort.mergesort(arr);
    int numDups = 0;
    for (int i = 1; i < arr.length; i++) {
        if (arr[i] == arr[i - 1]) {
            numDups++;
} }
    return numDups;
}

これの最悪の場合の時間の複雑さを見つけようとしています。私はマージソートが知っているnlog(n)し、私のforループではデータセット全体を反復処理しているので、それはとしてカウントされnます。しかし、これらの数値をどうするかはわかりません。合計するだけですか?もしそうするなら、どうすればいいですか?


1
補足:ハッシュテーブルを使用して、メモリ要件に応じてO(n)でこれを行うことができます。
corsiKa

回答:


67
O(n) + O(n log(n)) = O(n log(n))

Big Oの複雑さについては、重要な用語のみが重要です。 n log(n)支配nそれはあなたが気にすることを唯一の用語ですので。


4
これについて考えるもう1つの方法は、O(n)処理が実際にO(n log n)であると想像することです。まるで2つの独立したソートを行ったかのようです。その後、2 * O(n log n)になります。しかし、定数は抜け落ちているので、O(n log n)に戻ります。
ジョナサンユニス14年

4
@Jonathanこれは実際には機能しますが、O(n)がO(n log(n))と等しくないことは事実です。したがって、定期的に使用することはお勧めしません。
アザ14年

17
@Emrakul実際には、理論は実用的であると同時に理論的にも正しいと思います。O(n)はO(n log(n))の適切なサブセットです。したがって、f(n)がO(n)に属する場合、O(n log(n))にも属します。
エモリー14年

17
我々が言うときことに留意すべきであるf(n) is O(g(n))私たちが本当に言っている機能ということですf is a member of the set of functions that grows at the rate of at most g(n) over the long term。これは、のすべてのメンバーがのメンバーでO(n)あることを意味しますO(n*log(n))+以下のような式でO(f(n)) + O(g(n))実際にセット組合を参照してください(実際に知識をひけらかすだあなたのその、あなたは本当に∪使用する必要があります)。
ライライアン14年

3
@LieRyanもともと、それは和集合ではなく、和を設定します:A + B = { a + b | a in A, b in B }。フォームのセットの場合、セットのO(g(n))一方は常に他方のサブセットであり、両方とも合計に対して不変であるため(つまり、A + A = A)、これはセット結合と同じです。(おっと、ネイトは本質的に同じことを書いた)。
パエロエベルマン14

56

方法を説明し、の定義を思い出しましょうO。使用するのは、無限大での制限です。

あなたはの漸近的境界を対応する2つの操作を行うことを伝えるに正しいO(n)O(nlog(n))が、単一バウンドにそれらを組み合わせることは二つの機能を追加するなど、単純なようではありません。あなたの関数は少なくともO(n)時間がかかり、そして少なくとも時間がかかることを知っていますO(nlog(n))。だから、本当にあなたの関数の複雑性クラスはの労働組合であるO(n)O(nlog(n))しかしO(nlog(n))のスーパーセットであるO(n)ので、本当にそれだけですO(nlog(n))


12
+1これが答えです。compsci用語を使用して、より正確に答えを説明します。

5

手書きで設定する場合は、おおよそ次のようになります。

合計時間がan + bn log(n)であるとします。ここで、aとbは定数です(低次の項は無視します)。

nが無限大になると(an + bn log(n))/ n log(n)-> a / log(n)+ b-> b

したがって、合計時間はO(bn log(n))= O(n log(n))です。


2

O()の定義から始めます。

O(n log n)は、「nが大きい場合、C n log n未満」を意味します。

O(n)は、「nが大きい場合、D n未満」を意味します。

両方を追加すると、結果はC n log n + D n <C n log n + D n log n <(C + D)n log n = O(n log n)未満になります。

一般に、大きなnに対してf(n)> C g(n)でC> 0の場合、O(f(n))+ O(g(n))= O(f(n))です。そして、O()の定義を使用していくつかのケースを実行すると、何ができて何ができないかがわかります。


1

大きなO表記はセットとして定義されます:

ここに画像の説明を入力してください

したがってここに画像の説明を入力してください、すべての関数が含まれます-任意の大きなポイントから開始ここに画像の説明を入力してください-常にgよりも小さい。

さて、ある関数を持っているときにここに画像の説明を入力してください、gよりもゆっくりと増加する別の関数を実行すると、確かに2gよりもゆっくりと増加します。したがって、gより遅いものを実行しても、複雑度クラスは変わりません。

より正式には:

f、h \ in \ mathcal {O}(g)\ Rightarrow(f + h)\ in \ mathcal {O}(g)

それは簡単に証明できます。

TL; DR

まだです n log(n)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.