web-dev-qa-db-ja.com

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

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

_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;
}
_

私はこれの最悪の場合の時間の複雑さを見つけようとしています。私はmergesortがnlog(n)であることを知っており、私のforループではnとしてカウントされるように、データセット全体を繰り返し処理しています。しかし、これらの数値をどうするかわかりません。それらを一緒に合計する必要がありますか?それを行うとしたら、どうすればよいでしょうか。

23
_O(n) + O(n log(n)) = O(n log(n))
_

Big Oの複雑さの場合、重要なのは主要な用語だけです。 n log(n)nを支配しているので、それだけが重要な用語です。

66
Justin Cave

それを私たちの方法で推論し、Oの定義を思い出してみましょう。私が使用するのは、無限の限界のためです。

O(n)O(nlog(n))の対応する漸近境界を使用して2つの演算を実行することは正しいですが、それらを単一の境界に結合することは、2つの関数を追加するほど簡単ではありません。あなたの関数は少なくともO(n)時間と少なくともO(nlog(n))時間かかることを知っています。したがって、実際の関数の複雑性クラスはO(n)O(nlog(n))の和集合ですが、O(nlog(n))O(n)のスーパーセットであるため、実際にはただO(nlog(n))です。

57
davidk01

ロングハンドで設定する場合、おおよそ次のようになります。

合計時間が次のとおりであるとします。

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

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

5
richardb

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()の定義を使用していくつかのケースを実行すると、何ができるか、何ができないかがわかります。

2
gnasher729

ビッグO表記はセットとして定義されます。

enter image description here

そう enter image description here すべての関数が含まれています-任意の大きなポイントから開始 enter image description here -常にgよりも小さい。

さて、あなたが中にある関数を持っているとき enter image description here そして、gよりもゆっくりと増加する別の1つを実行すると、2gよりもゆっくりと増加します。したがって、gよりも遅いものを実行しても、複雑度クラスは変更されません。

より正式には:

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

簡単に証明できます。

TL; DR

まだです n log(n)

1
Martin Thoma