DEV Community

Anmol Jindal
Anmol Jindal

Posted on • Originally published at Medium on

Why Your Recursive Fibonacci Is a Time-Consuming Monster (And How DP Saves Your Day)

In this blog, I’ll explain why naive recursion is a terrible idea for Fibonacci, how dynamic programming (DP) can fix it, and how you can write efficient Fibonacci code that’s easy to understand

What is Fibonacci?

Fibonacci
Image by Gerd Altmann from Pixabay

The Fibonacci sequence is a series of numbers where each number is the sum of the two preceding ones.

The Fibonacci sequence, denoted as fib(n), starts like this:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …

The nth Fibonacci number is the sum of (n-1)th and (n-2)th Fibonacci numbers. Simple, right?

The Naive Recursive Approach: Welcome to Exponential Hell

The first instinct of everyone is to write this beautiful but deadly code:

int fib(int n) {
    if (n <= 1)
        return n;
    return fib(n - 1) + fib(n - 2);
}
Enter fullscreen mode Exit fullscreen mode

At first glance, this function looks simple and neat. But don’t be fooled , it ends up recalculating the same values so many times, it might as well be stuck in an infinite loop of inefficiency.

Dynamic Programming to the Rescue

Dynamic programming is basically caching the results of expensive function calls and reusing them when needed by using a concept called memoization.

Here’s how you can do it:

int fib_memo(int n, int memo[]) {
    if (n <= 1)
        return n;
    if (memo[n] != -1)
        return memo[n];
    memo[n] = fib_memo(n - 1, memo) + fib_memo(n - 2, memo);
    return memo[n];
}
Enter fullscreen mode Exit fullscreen mode

You just need to initialize the memo array with -1 and call fib_memo(n, memo). This cuts the time complexity down to O(n), which is a massive improvement.

Tabulation: The Bottom-Up Approach

If recursion isn’t your thing, try tabulation. It’s a bottom-up method that builds the solution from the ground up:

int fib_tab(int n) {
    int dp[n + 1];
    dp[0] = 0;
    dp[1] = 1;

    for (int i = 2; i <= n; i++) {
        dp[i] = dp[i - 1] + dp[i - 2];
    }
    return dp[n];
}
Enter fullscreen mode Exit fullscreen mode

This method also runs in O(n) time and uses O(n) space.

Real-Life Analogy: Climbing Stairs

Picture yourself climbing a staircase where you can take either 1 or 2 steps at a time. The total number of distinct ways to reach the nth step corresponds exactly to the nth Fibonacci number.

Dynamic Programming (DP) comes in handy by remembering how many ways you’ve already counted for each step, saving your code from doing the same calculation over and over again.

Bonus Challenge: Space Optimization

Try implementing Fibonacci using just two variables and a loop, which brings space complexity down to O(1):

int fib_optimized(int n) {
    if (n <= 1)
        return n;
    int a = 0, b = 1, c;
    for (int i = 2; i <= n; i++) {
        c = a + b;
        a = b;
        b = c;
    }
    return b;
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

Dynamic programming is your secret weapon against inefficient recursive hell. Whether you choose memoization or tabulation, mastering DP will elevate your coding game and prepare you for tougher algorithmic challenges.

If you found this blog helpful, hit that clap button, share it with your friends, and follow me for more tips on DSA, and coding challenges.

Connect with me on LinkedIn and check out my repos on GitHub for code snippets and more.

Top comments (0)