By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
"This single problem tests recursion, memoization, dynamic programming, and space optimization—master it, and you’ll crush 1 out of every 3 FAANG onsite interviews where DP comes up."
Before diving in, ensure you understand: 1. Recursion – Base cases, recursive calls, call stack. 2. Memoization (Caching) – Storing computed results to avoid redundant work. 3. Dynamic Programming (DP) – Breaking problems into overlapping subproblems.
fib(n) = fib(n-1) + fib(n-2)
fib(n)
fib(0)
fib(n) ≈ φⁿ / √5
Mental checklist for every Fibonacci problem:
fib(0) = 0
1
fib(0) = 0, fib(1) = 1
What’s the input range? (If n ≤ 30, recursion is fine. If n ≥ 1000, use DP.)
n ≤ 30
n ≥ 1000
Write the recursive formula:
Base cases: fib(0) = 0, fib(1) = 1
fib(1) = 1
Check for overlapping subproblems:
If fib(n) is computed multiple times, memoization is needed.
Choose the right approach:
n
Large n (10⁶+): Space-optimized DP or matrix exponentiation.
Implement & test edge cases:
n = 0
n = 1
n = 2
n = 5
n = 10
Check for integer overflow (use long if needed).
long
Optimize space (if required):
Problem: Compute the nth Fibonacci number (naive recursion).
Thought Process: - Directly implement the recursive formula. - Time: O(2ⁿ) (exponential, inefficient). - Space: O(n) (call stack depth).
Code (Python):
def fib(n: int) -> int: if n == 0: return 0 if n == 1: return 1 return fib(n - 1) + fib(n - 2)
Why this works: - Follows the mathematical definition directly. - But: Fails for n > 30 due to exponential time.
n > 30
Problem: Optimize the recursive solution using memoization.
Thought Process: - Store computed fib(n) in a hash map to avoid recomputation. - Time: O(n) (each fib(i) computed once). - Space: O(n) (memoization table + call stack).
fib(i)
def fib(n: int, memo={}) -> int: if n in memo: return memo[n] if n == 0: return 0 if n == 1: return 1 memo[n] = fib(n - 1, memo) + fib(n - 2, memo) return memo[n]
Why this works: - Eliminates redundant recursive calls by caching results. - Tradeoff: Still uses O(n) space due to recursion stack.
Problem: Compute fib(n) in O(n) time and O(1) space.
Thought Process: 1. Bottom-Up (Tabulation): - Iteratively compute fib(0) to fib(n) in an array. - Time: O(n), Space: O(n). 2. Space Optimization: - Only track the last two values (prev1, prev2). - Time: O(n), Space: O(1).
prev1
prev2
# Bottom-Up (Tabulation) def fib(n: int) -> int: if n == 0: return 0 dp = [0] (n + 1) dp[1] = 1 for i in range(2, n + 1): dp[i] = dp[i - 1] + dp[i - 2] return dp[n] # Space-Optimized def fib(n: int) -> int: if n == 0: return 0 prev2, prev1 = 0, 1 for _ in range(2, n + 1): curr = prev1 + prev2 prev2, prev1 = prev1, curr return prev1
Why this works: - Tabulation: Builds the solution iteratively, avoiding recursion stack issues. - Space Optimization: Only stores the last two values, reducing space to O(1).
n > 1000
n+1
n=2
fib(2)=1
fib(100)
int
BigInteger
-1
"Alright, let’s lock this in. The Fibonacci problem is your gateway to dynamic programming. Here’s the playbook:
n=0
n=1
If the interviewer asks for space optimization, you now know how to drop from O(n) to O(1). If they ask for time complexity, you can confidently say O(n) for DP and O(2ⁿ) for naive recursion. Walk in, write the code, and own the problem. You’ve got this!
fib(5)
Now go crush that interview! ?
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.