Recursive Fibonacci in JavaScript (Time Complexity: Exponential)


The Fibonacci numbers, commonly denoted F(n) form a sequence, called the Fibonacci sequence, such that each number is the sum of the two preceding ones, starting from 0 and 1. That is,

F(0) = 0, F(1) = 1
F(n) = F(n - 1) + F(n - 2), for n > 1.

Write a recursive function that given n, returns F(n).

Example 1:

Input: n = 2
Output: 1
Explanation: F(2) = F(1) + F(0) = 1 + 0 = 1.

Example 2:

Input: n = 3
Output: 2
Explanation: F(3) = F(2) + F(1) = 1 + 1 = 2.

Example 3:

Input: n = 4
Output: 3
Explanation: F(4) = F(3) + F(2) = 2 + 1 = 3.

Constraints:
  • 0 <= n <= 30
Note:

Don't worry about the time and space complexities of your algorithm.


Hints:

Inside the function, we should first check the base case: if n is less than 2, then we should return n.

If n >= 2, since F(n) = F(n - 1) + F(n - 2), we should return fibonacci(n - 1) + fibonacci(n - 2).

Understanding the Problem

The core challenge of this problem is to compute the nth Fibonacci number using a recursive approach. The Fibonacci sequence is a classic example in computer science and has applications in various fields such as algorithm analysis, financial modeling, and biological settings.

Potential pitfalls include not handling the base cases correctly and not optimizing the recursive calls, which can lead to excessive computation time for larger values of n.

Approach

To solve this problem, we can start with a naive recursive approach:

This naive approach is simple but not optimal due to its exponential time complexity. Each call to the function results in two more calls, leading to a large number of redundant calculations.

Optimized Solutions

To optimize, we can use memoization or dynamic programming:

Algorithm

Naive Recursive Approach

/**
 * Naive recursive approach to find the nth Fibonacci number.
 * @param {number} n - The index of the Fibonacci sequence.
 * @return {number} - The nth Fibonacci number.
 */
function fibonacci(n) {
  // Base cases
  if (n < 2) {
    return n;
  }
  // Recursive case
  return fibonacci(n - 1) + fibonacci(n - 2);
}

Memoized Recursive Approach

/**
 * Memoized recursive approach to find the nth Fibonacci number.
 * @param {number} n - The index of the Fibonacci sequence.
 * @param {Object} memo - The cache to store previously computed Fibonacci numbers.
 * @return {number} - The nth Fibonacci number.
 */
function fibonacciMemo(n, memo = {}) {
  // Base cases
  if (n < 2) {
    return n;
  }
  // Check if result is already in the cache
  if (memo[n]) {
    return memo[n];
  }
  // Compute and store the result in the cache
  memo[n] = fibonacciMemo(n - 1, memo) + fibonacciMemo(n - 2, memo);
  return memo[n];
}

Dynamic Programming Approach

/**
 * Dynamic programming approach to find the nth Fibonacci number.
 * @param {number} n - The index of the Fibonacci sequence.
 * @return {number} - The nth Fibonacci number.
 */
function fibonacciDP(n) {
  if (n < 2) {
    return n;
  }
  const fib = [0, 1];
  for (let i = 2; i <= n; i++) {
    fib[i] = fib[i - 1] + fib[i - 2];
  }
  return fib[n];
}

Complexity Analysis

Naive Recursive Approach: Time complexity is O(2^n) due to redundant calculations. Space complexity is O(n) due to the call stack.

Memoized Recursive Approach: Time complexity is O(n) as each Fibonacci number is computed once. Space complexity is O(n) due to the cache and call stack.

Dynamic Programming Approach: Time complexity is O(n) as each Fibonacci number is computed once. Space complexity is O(n) due to the array used to store Fibonacci numbers.

Edge Cases

Edge cases include:

Testing

To test the solution comprehensively, consider the following test cases:

Use a testing framework like Jest or Mocha to automate these tests.

Thinking and Problem-Solving Tips

When approaching such problems:

Conclusion

Understanding and solving the Fibonacci sequence problem using recursion helps in grasping fundamental concepts of algorithm design and optimization. Practice and exploration of different approaches are key to mastering such problems.

Additional Resources

For further reading and practice: