web-dev-qa-db-ja.com

再帰的フィボナッチアルゴリズムの空間の複雑さは何ですか?

これは、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)もありませんか?

17

それでも混乱している人がいる場合は、フィボナッチ数列を生成する際のスペースの複雑さについて説明しているこのYouTubeビデオを必ずチェックしてください。 フィボナッチ空間の複雑さ

プレゼンターは、空間の複雑さがO(n)であり、再帰ツリーの高さがnである理由を本当に明確にしました。

11

ここにヒントがあります。以下の例のように、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)。

20
selbie

私が見ているように、プロセスは一度に1つの再帰のみを下降します。最初の(f(i-1))はN個のスタックフレームを作成し、他の(f(i-2))はN/2を作成します。したがって、最大のものはNです。他の再帰ブランチはそれ以上のスペースを使用しません。

つまり、スペースの複雑さはNだと思います。

f(i-2)はf(i-1)スペース。

2
Richard