フィボナッチシーケンスのn番目の項を計算できるさまざまな手段でコードを実装しようとしましたが、私が学んだことを検証したいと考えています。フィボナッチのさまざまな実装のBig-O
次のように反復的な実装は次のとおりです。
public int iterativeFibonacci(int n)
{
if (n == 1) return 0;
else if (n == 2) return 1;
int i = 0, j = 1, sum = 0;
for (; (n-2) != 0; --n)
{
sum = i + j;
i = j;
j = sum;
}
return sum;
}
次のように再帰的な実装は次のとおりです。 -
public int recursiveFibonacci(int n)
{
if (n == 1) return 0;
else if (n == 2) return 1;
return recursiveFibonacci(n-1) + recursiveFibonacci(n-2);
}
次のようにメモ化の実装は次のとおりです。 -
public int memoizedFibonacci(int n)
{
if (n <= 0) return -1;
else if (n == 1) return 0;
else if (n == 2) return 1;
if (memory[n-1] == 0)
memory[n-1] = memoizedFibonacci(n-1);
if (memory[n-2] == 0)
memory[n-2] = memoizedFibonacci(n-2);
return memory[n-1]+memory[n-2];
}
私は」これらの実装のBig-Oを理解しようとすると疑いがあります。私は反復実装がO(n)であると信じています.N-2回ループします。
再帰関数では、値が再計算されているため、O(n^2)だと思います。
memoized関数では、memoizationに基づいて値の半分以上がアクセスされます。私はそれを読んだ問題のスペースを減らすために一定の時間がかかる場合、とそのアルゴリズムはO(ログN)です。一定量。メモの実装がO(n)という複雑さを抱いていると思いますか?もしそうなら、3つすべての中で反復的な実装が最善ではないでしょうか? (memoizationが必要とする追加のメモリを使用しないため)。
プログラミング競技でのこれらのような線形再来問題は、通常、「行列累乗」によって解決されます。この[blogpost](http://fusharblog.com/solving-linear-recurrence-for-programming-contest/)には、フィボナッチシリーズのC++の例があります。 – plesiv