web-dev-qa-db-ja.com

2つのforループの時間計算量

だから私は次の時間の複雑さを知っています:

for(i;i<x;i++){
   for(y;y<x;y++){
      //code
   }
}

n ^ 2です

しかし、次のようになります。

for(i;i<x;i++){
   //code
}
for(y;y<x;y++){
   //code
}

n + nになりますか?

22
James

Big-O表記は絶対的な複雑さを比較することではなく、相対的な複雑さを比較することだけなので、O(n + n)は実際にはO(n)と同じです。 xを2倍にするたびに、コードは以前の2倍の時間がかかります。つまり、O(n)です。コードが2、4、または20ループを実行するかどうかは関係ありません。これは、100要素にかかる時間に関係なく、200要素の場合は2倍、10,000要素の場合は100倍の時間がかかるためです。その内のどのループ内で費やされます。

そのため、big-Oは絶対速度について何も言っていません。 O(n ^ 2)関数f()は常にO(log n)関数g()よりも遅いと考える人は誰でも間違っています。big-O表記は、 nを増やし続けると、g()が速度でf()を追い抜くポイントがありますが、nが常にそれを下回っている場合)実際には、実際のプログラムコードではf()は常にg()よりも高速になる可能性があります。

例1
f(x)は単一の要素で5ミリ秒かかり、g(x)は単一の要素で100ミリ秒かかると仮定しましょう。 f(x) is O(n ^ 2)、g(x) is O(log2 n)。時間グラフは次のようになります。

enter image description here
注:最大7つの要素、f(x)は、O(n ^ 2)であっても高速です。
8つ以上の要素の場合、g(x)の方が高速です。

例2
バイナリ検索はO(log n)であり、理想的なハッシュテーブル(衝突なし)はO(1)ですが、私を信じてください。実際には、ハッシュテーブルは必ずしもバイナリ検索よりも高速であるとは限りません。優れたハッシュ関数を使用すると、文字列のハッシュは、バイナリ検索全体よりも時間がかかる可能性があります。一方、貧弱なハッシュ関数を使用すると、衝突が多く発生します。衝突が多いほど、ハッシュテーブルのルックアップは実際にはO(1)になりません。これは、ほとんどのハッシュテーブルが、ルックアップをO(log2 n)またはO(n)ですら。

38
Mecki

2nになるので、そうです。

通常はO(n)として表されますが、2次ではなく線形であると見なされます。

もちろん、ループ内のコードによって異なりますが、すでにご存知だと思います。

12
Nick Brunt