Memoization to Optimize Recursion in DSA C - Time & Space Complexity
We want to see how using memoization changes the speed of recursive functions.
How does remembering past answers help us do less work?
Analyze the time complexity of the following code snippet.
int fib(int n, int memo[]) {
if (n <= 1) return n;
if (memo[n] != -1) return memo[n];
memo[n] = fib(n-1, memo) + fib(n-2, memo);
return memo[n];
}
// memo array initialized with -1 for all indices
This code calculates Fibonacci numbers using recursion and stores results to avoid repeated work.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive calls to fib with memoization check.
- How many times: Each unique fib(n) is computed once; repeated calls return stored result immediately.
Without memoization, calls grow very fast because many repeat. With memoization, each number is calculated once.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 calls |
| 100 | About 100 calls |
| 1000 | About 1000 calls |
Pattern observation: The work grows roughly in a straight line with n, not exponentially.
Time Complexity: O(n)
This means the function does work proportional to n, calculating each Fibonacci number once.
[X] Wrong: "Memoization doesn't change the time complexity; recursion is always slow."
[OK] Correct: Memoization saves results so repeated calls are fast, reducing exponential calls to linear.
Understanding memoization shows you can improve slow recursive solutions by saving work, a key skill in problem solving.
"What if we removed the memo array and just used plain recursion? How would the time complexity change?"
Practice
memoization in recursive functions?Solution
Step 1: Understand what memoization does
Memoization saves the results of function calls so they don't need to be recalculated.Step 2: Identify the benefit in recursion
This reduces repeated work and speeds up recursive functions.Final Answer:
To store results of expensive function calls and reuse them -> Option BQuick Check:
Memoization = Store and reuse results [OK]
- Thinking memoization slows down the function
- Confusing memoization with converting recursion to loops
- Believing memoization removes variables
Solution
Step 1: Check valid C array declaration
In C, arrays are declared with type, name, and size in square brackets.Step 2: Identify correct syntax
int memo[100] = {0}; usesint memo[100] = {0};which initializes all elements to zero correctly.Final Answer:
int memo[100] = {0}; -> Option CQuick Check:
Array declaration with size and initialization = int memo[100] = {0}; [OK]
- Using parentheses instead of brackets for arrays
- Assigning a single int instead of an array
- Not initializing the array to zero
int memo[100] = {0};
int fib(int n) {
if (n <= 1) return n;
if (memo[n] != 0) return memo[n];
memo[n] = fib(n-1) + fib(n-2);
return memo[n];
}
int main() {
printf("%d", fib(5));
return 0;
}Solution
Step 1: Trace fib(5) with memoization
fib(5) = fib(4) + fib(3), and so on, with memo storing results to avoid repeats.Step 2: Calculate Fibonacci values
fib(0)=0, fib(1)=1, fib(2)=1, fib(3)=2, fib(4)=3, fib(5)=5.Final Answer:
5 -> Option AQuick Check:
fib(5) = 5 [OK]
- Confusing fib(5) with fib(6)
- Ignoring memoization effect on output
- Mistaking base cases
int memo[100] = {0};
int fact(int n) {
if (n == 0) return 1;
if (memo[n] != 0) return memo[n];
memo[n] = n * fact(n - 1);
return memo[n];
}
int main() {
printf("%d", fact(5));
return 0;
}Solution
Step 1: Understand memo check condition
The code checks if memo[n] != 0 to decide if value is cached.Step 2: Identify problem with zero initialization
Since factorial(0) = 1, memo[1] will be 0 initially, but 0 is a valid value for uninitialized. This causes confusion.Step 3: Correct approach
Initialize memo array with -1 to mark uncalculated values, so 0 is a valid cached result.Final Answer:
Memo array is not initialized to -1 to detect uncalculated values -> Option AQuick Check:
Use -1 to mark uncalculated memo entries [OK]
- Assuming zero means uncalculated without initialization
- Changing base case incorrectly
- Thinking recursion must be replaced by iteration
n stairs taking 1 or 2 steps at a time. Which memoization approach below correctly stores intermediate results to avoid repeated calculations?Solution
Step 1: Understand problem and memoization need
Number of ways to climb stairs is a classic recursion problem with overlapping subproblems.Step 2: Choose correct memoization method
Using an array sized n+1 initialized with -1 allows storing results for each step count to reuse.Final Answer:
Use an arrayint memo[n+1]initialized with -1, store results atmemo[i]for steps i -> Option DQuick Check:
Array memo with -1 initialization stores intermediate results [OK]
- Not initializing memo array properly
- Using global counters without memoization
- Using complex data structures unnecessarily
Ready to prove it?
Pass the test and this pattern moves unknown
