web-dev-qa-db-ja.com

ビッグO-O(log(n))コード例

Big O表記のように、「O(1)」は次のコードを記述できます。

O(1):

    for (int i = 0; i < 10; i++) {
        // do stuff 
        a[i] = INT;
    }

O(n):

    for (int i = 0; i < n; i++) {
        // do stuff 
        a[i] = INT;
    }

O(n^2):
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            // do stuff
            a[i][j] = INT;
        }
    }
  • O(log(n))はどのコードを記述できますか?

別の質問:

  • 「ビッグOの問題」にはどのような解決策がありますか(大量のデータを入力として取得する場合の対処方法)。
21
Langkiller

古典的な例:

while (x > 0) {  
   x/=2;  
}  

これは次のようになります:

Iteration |   x
----------|--------
    0     |   x
    1     |  x/2
    2     |  x/4
   ...    |  ...
   ...    |  ...
    k     |  x/2^k 

2k = x→両側にログを適用→k = log(x)

38
Maroun

O(logn)については、分割統治戦略を含むコードをご覧ください例:マージソートとクイックソート(予想実行時間はO(nlogn)これらの場合)

3
attaboy182

定義から、log(n)(ここでは、底が2のログを意味しますが、底は本当に問題ではありません)は、nを取得するために2を掛ける必要がある回数です。したがって、O(log(n))コード例は次のとおりです。

i = 1
while(i < n)
    i = i * 2
    // maybe doing addition O(1) code

実際のコード例では、O(log(n))でバイナリ検索、バランスの取れたバイナリ検索ツリー、多くの再帰アルゴリズム、優先度キューで満たすことができます。

3
pkacprzak

バイナリ検索はO(log(n))の例です。 http://en.wikipedia.org/wiki/Binary_search_algorithm

1

二分探索の場合、反復の最大数、つまり探索空間を半分に分割できる最大回数を見つけようとしています。これは、1に到達するまで、検索スペースのサイズnを2で繰り返し除算することで実現されます。

Nを2で割る必要がある回数をラベルxに与えましょう。 2で割ると、x回は2 ^ xで割ることに相当するため、この方程式を解く必要があります。

n/2 ^ x = 1、n = 2 ^ x、

したがって、対数、x = log(n)を使用すると、BIG-バイナリ検索のOはO(log(n))になります。

繰り返しますが、xは、サイズnのスペースをサイズ1に絞り込む前に半分に分割できる回数です。

http://www.quora.com/How-would-you-explain-O-log-n-in-algorithms-to-1st-year-undergrad-student

0
bsingh

記述した複雑度の低いアルゴリズムは、複雑度の高いアルゴリズムのサブセットであることを強調する価値があるかもしれません。言い換えると、

for (int i = 0; i < 10; i++) {
    // do stuff 
    a[i] = INT;
}

o(1)だけでなく、O(n)、O(n²)にもあります。賢くなりたい場合は、O(log(n))を使用します。なぜですか?すべての一定時間アルゴリズムは、いくつかの線形関数、二次関数などによって制限されているためです。

「ビッグOの問題」にはどのような解決策がありますか(大量のデータを入力として取得する場合の対処方法)。

この質問は私にはあまり意味がありません。 「大量のデータ」はかなり恣意的です。それでも、時間の複雑さを測定するのはBig Oだけではないことに注意してください。最悪の場合の時間の複雑さの測定とは別に、ベストケースと平均のケースを調べることもできますが、これらは計算が少し難しい場合があります。

0
lealand