Loading problems...
TL;DR: The optimal solution uses an iterative bottom-up approach (Dynamic Programming) to calculate the -th value by summing the two previous values, reducing the time complexity to linear and space to constant.
The Fibonacci Number problem asks us to compute the -th term in the Fibonacci sequence. The sequence is defined recursively where each number is the sum of the two preceding ones. Specifically, , , and for any , . While the mathematical definition is recursive, serves as a fundamental introduction to optimizing recursive problems using Dynamic Programming.
The most intuitive way to solve the Fibonacci Number problem is to directly translate the mathematical recurrence relation into code using recursion.
The algorithm functions as follows:
python# Pseudo-code for Brute Force function fib(n): if n <= 1: return n return fib(n - 1) + fib(n - 2)
Why this approach fails: The time complexity of this recursive solution is . This exponential growth occurs because the algorithm re-calculates the same subproblems multiple times. For example, to calculate , it calculates and . However, the calculation of also calculates . As increases, the number of redundant operations explodes, leading to a Time Limit Exceeded (TLE) on larger constraints or significant inefficiency on moderate ones.
The core insight needed to move from the brute force approach to the optimal solution is the recognition of overlapping subproblems. In the recursion tree, the value of fib(k) is computed repeatedly for the same k.
By applying the Dynamic Programming pattern, we can eliminate this redundancy. Instead of starting from and working backward (Top-Down), we start from the base cases ( and ) and work forward (Bottom-Up).
Visual Description: Imagine a linear array of size . We know the values at index 0 and index 1. To fill index 2, we simply look at the values at indices 0 and 1. To fill index 3, we look at indices 1 and 2. The dependency graph is a simple straight line where node depends only on and . Since we process in increasing order, the values needed for the current step are always available and already computed.

prev2 = 0 (corresponds to ).prev1 = 1 (corresponds to ).current = prev1 + prev2.prev2 becomes the old prev1.prev1 becomes the calculated current.prev1 holds the value of .The correctness is proven via mathematical induction.
prev1 correctly holds and prev2 correctly holds . The algorithm computes current = prev1 + prev2, which is . By the definition of the Fibonacci sequence, this sum is exactly .prev1 is .cppclass Solution { public: int fib(int n) { // Base cases if (n == 0) return 0; if (n == 1) return 1; // DP state variables int prev2 = 0; // F(0) int prev1 = 1; // F(1) // Iterative Bottom-Up Calculation for (int i = 2; i <= n; ++i) { int current = prev1 + prev2; prev2 = prev1; prev1 = current; } return prev1; } };
javaclass Solution { public int fib(int n) { // Base cases if (n == 0) return 0; if (n == 1) return 1; // DP state variables int prev2 = 0; // F(0) int prev1 = 1; // F(1) // Iterative Bottom-Up Calculation for (int i = 2; i <= n; i++) { int current = prev1 + prev2; prev2 = prev1; prev1 = current; } return prev1; } }
pythonclass Solution: def fib(self, n: int) -> int: # Base cases if n == 0: return 0 if n == 1: return 1 # DP state variables prev2, prev1 = 0, 1 # Iterative Bottom-Up Calculation for _ in range(2, n + 1): current = prev1 + prev2 prev2 = prev1 prev1 = current return prev1
prev1, prev2) regardless of the input size . This is an improvement over the standard DP array approach.The DP - 1D Array (Fibonacci Style) pattern is foundational. The logic of depending on the previous one or two states applies directly to:
Why does my recursive solution get a Time Limit Exceeded (TLE)?
Why is my result incorrect for or ?
Why use an array dp[n+1] instead of variables?