Fibonacci Using DP in DSA C++ - Time & Space Complexity
We want to understand how fast the Fibonacci numbers can be calculated using dynamic programming.
How does the time needed grow as we ask for bigger Fibonacci numbers?
Analyze the time complexity of the following code snippet.
int fibonacci(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];
}
This code calculates the nth Fibonacci number by building up answers from smaller numbers using a table.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The for-loop that fills the dp array from 2 to n.
- How many times: Exactly n-1 times (from 2 up to n).
Each new Fibonacci number requires one addition and one assignment inside the loop.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 9 additions and assignments |
| 100 | About 99 additions and assignments |
| 1000 | About 999 additions and assignments |
Pattern observation: The number of operations grows roughly in a straight line as n increases.
Time Complexity: O(n)
This means the time to find the nth Fibonacci number grows directly in proportion to n.
[X] Wrong: "Calculating Fibonacci with recursion is always fast because it just calls itself."
[OK] Correct: Simple recursion repeats many calculations, making it much slower than this dynamic programming approach.
Knowing how to use dynamic programming to speed up Fibonacci calculations shows you understand how to avoid repeated work, a key skill in many coding problems.
"What if we used recursion with memoization instead of a loop? How would the time complexity change?"
Practice
Solution
Step 1: Understand recursion vs DP
Simple recursion recalculates the same Fibonacci numbers many times, causing inefficiency.Step 2: Role of DP in Fibonacci
DP stores previously calculated Fibonacci numbers in a table (memoization or tabulation) to avoid repeated work.Final Answer:
It avoids repeated calculations by storing intermediate results. -> Option BQuick Check:
DP = store results to avoid repeats [OK]
- Thinking DP uses less memory than recursion
- Confusing DP with simple recursion
- Believing DP avoids addition operations
Solution
Step 1: Identify Fibonacci base cases
Fibonacci sequence starts with fib(0) = 0 and fib(1) = 1.Step 2: Check initialization correctness
int fib[10]; fib[0] = 0; fib[1] = 1; correctly sets fib[0] = 0 and fib[1] = 1, matching the base cases.Final Answer:
int fib[10]; fib[0] = 0; fib[1] = 1; -> Option AQuick Check:
fib[0]=0, fib[1]=1 base cases [OK]
- Starting fib from index 1 instead of 0
- Swapping values of fib[0] and fib[1]
- Initializing wrong indices
int fib[6];
fib[0] = 0; fib[1] = 1;
for(int i = 2; i < 6; i++) {
fib[i] = fib[i-1] + fib[i-2];
}
std::cout << fib[5];Solution
Step 1: Calculate Fibonacci values step-by-step
fib[0]=0, fib[1]=1 fib[2]=1, fib[3]=2, fib[4]=3, fib[5]=5Step 2: Identify output
The code prints fib[5], which is 5.Final Answer:
5 -> Option AQuick Check:
fib[5]=5 [OK]
- Confusing fib[5] with fib[6]
- Off-by-one errors in loop
- Incorrect addition order
int fib[10];
fib[0] = 0;
fib[1] = 1;
for(int i = 1; i < 10; i++) {
fib[i] = fib[i-1] + fib[i-2];
}
std::cout << fib[9];Solution
Step 1: Analyze loop start index
The loop starts at i=1, but fib[1] is already initialized. Calculating fib[1] again causes fib[-1] access (invalid).Step 2: Correct loop start
Loop should start at i=2 to use fib[i-1] and fib[i-2] safely.Final Answer:
Change loop start to i = 2 -> Option DQuick Check:
Loop from i=2 avoids invalid index [OK]
- Starting loop at 1 causing invalid access
- Changing base case values incorrectly
- Extending loop beyond array size
Solution
Step 1: Consider data type size
50th Fibonacci number is very large; int cannot hold it, unsigned long long can hold bigger values.Step 2: Choose DP approach
Bottom-up DP avoids recursion overhead and stack issues, making it efficient for large n.Final Answer:
Use a vector of unsigned long long and bottom-up DP to avoid recursion overhead. -> Option CQuick Check:
Big number + bottom-up DP = efficient and safe [OK]
- Using int causing overflow
- Using recursion causing stack overflow
- Ignoring data type limits
Ready to prove it?
Pass the test and this pattern moves unknown
