次のコードは、指定された数nのすべての素因数を返します。アルゴリズムの背後にある次のアルゴリズムの実行時間はどのくらいですか?
アプローチ:数字上
反復(すなわち、> = 2)NまでI /素因数を取得します。
内部ループは、単純に現在の素数で割ることによって数値のサイズを減らし、同じ素数が複数回現れた場合、分割を継続します。
ifステートメントは、最後の&をn> 2の最も高い素数に加算します。これは、nがその時間までにその値に縮小されているためです。
static List<Integer> getAllPrimes(int n){
List<Integer> factors = new ArrayList<Integer>();
for(int i = 2 ; i <= n/i ; ++i){
while(n % i == 0){
factors.add(i); //LINE 1
n/=i;
}
}
if(n > 2){factors.add(n);}
return factors;
}
このアルゴリズムの実行時間はどのように決定されますか?以来、内側のループが反復されるたびに、素数ならインデックスiに基づいていくつかの一定値、例えばn/2、n/3 ....などでサイズが減少します。
これは、実際には、最悪の場合の複雑さを「O(sqrt(n))」とし、最悪の場合を「n」とする数の素因数分解のための標準アルゴリズムです。この[**記事**](http://www.geeksforgeeks.org/print-all-prime-factors-of-a-given-number/)をご覧ください。 –
最悪の場合、第1行目が数学や簡単なテストケースを使ってsqrt(n)回実行されることを証明できますか?私はそれを理解することができません –
最悪の場合、 'n'は内部whileループで減少しません。したがって、 'n'は' for'ループ全体の初期値と同じです。 'For'ループは' n'が初期値と同じなら 'O(sqrt(n))'時間をとります。そして最後に 'if(n> 2)'文で 'n'がリストに追加されます。このようにして、最悪の場合には 'O(sqrt(n))'をとります。最悪の場合の入力は素数です(例として11を取り、forループの実行時間を調べます)。 –