これは、Cracking the Coding Interview(5th Edition)からのフィボナッチ数列の再帰的実装です。
int fibonacci(int i) {
if(i == 0) return 0;
if(i == 1) return 1;
return fibonacci(i-1) + fibonaci(i-2);
}
このアルゴリズムの時間計算量に関するビデオを見た後、 Fibonacci Time Complexity 、このアルゴリズムがO(2n)。しかし、私はスペースの複雑さを分析するのに苦労しています。
私はオンラインでこれについて質問しました。
このQuoraスレッドで、作成者は次のように述べています。「あなたの場合、n個のスタックフレームf(n)、f(n-1)、f(n-2)、...、f(1) and O(1) "。2nスタックフレームはありませんか?f(n-2) 1フレームは実際の呼び出し用になりますf(n-2)しかし、f(n-1)からの呼び出しf(n-2)もありませんか?
それでも混乱している人がいる場合は、フィボナッチ数列を生成する際のスペースの複雑さについて説明しているこのYouTubeビデオを必ずチェックしてください。 フィボナッチ空間の複雑さ
プレゼンターは、空間の複雑さがO(n)であり、再帰ツリーの高さがnである理由を本当に明確にしました。
ここにヒントがあります。以下の例のように、printステートメントを使用してコードを変更します。
int fibonacci(int i, int stack) {
printf("Fib: %d, %d\n", i, stack);
if (i == 0) return 0;
if (i == 1) return 1;
return fibonacci(i - 1, stack + 1) + fibonacci(i - 2, stack + 1);
}
次に、この行をmainで実行します。
Fibonacci(6,1);
印刷される「スタック」の最大値はいくつですか。 「6」であることがわかります。 「i」の他の値を試してみると、出力された「スタック」値が、渡された元の「i」値を超えることはありません。
Fib(i-1)はFib(i-2)の前に完全に評価されるため、再帰のレベルがi
を超えることはありません。
したがって、O(N)。
私が見ているように、プロセスは一度に1つの再帰のみを下降します。最初の(f(i-1))はN個のスタックフレームを作成し、他の(f(i-2))はN/2を作成します。したがって、最大のものはNです。他の再帰ブランチはそれ以上のスペースを使用しません。
つまり、スペースの複雑さはNだと思います。
f(i-2)はf(i-1)スペース。