📖 Scenario: Imagine you want to find the number of ways to climb a staircase with a certain number of steps. You can climb either 1 or 2 steps at a time. This is a classic problem where recursion helps but can be slow without optimization.
🎯 Goal: You will build a program that uses recursion to find the number of ways to climb stairs and then optimize it using memoization to avoid repeated calculations.
📋 What You'll Learn
Create a recursive function to calculate ways to climb stairs
Add a dictionary to store results of subproblems (memoization)
Modify the recursive function to use the memo dictionary
Print the number of ways to climb a staircase with 5 steps
💡 Why This Matters
🌍 Real World
Memoization is used in many real-world problems like calculating Fibonacci numbers, optimizing search algorithms, and improving performance in games and simulations.
💼 Career
Understanding memoization helps in writing efficient code, which is a valuable skill for software developers, data scientists, and anyone working with algorithms.
Progress0 / 4 steps
1
Create a recursive function to count ways to climb stairs
Define a function called count_ways that takes an integer n representing the number of steps. Use recursion to return 1 if n is 0 or 1, otherwise return the sum of count_ways(n-1) and count_ways(n-2).
DSA Python
Hint
Think of the base cases when there are 0 or 1 steps. For other cases, add the results of the two smaller problems.
2
Create a memo dictionary to store results
Create an empty dictionary called memo outside the function to store previously calculated results.
DSA Python
Hint
This dictionary will help remember answers to smaller problems so you don't calculate them again.
3
Modify the function to use memoization
Update the count_ways function to check if n is in memo. If yes, return memo[n]. Otherwise, calculate the result recursively, store it in memo[n], and then return it.
DSA Python
Hint
Use the dictionary to save and reuse results to avoid repeated work.
4
Print the number of ways to climb 5 steps
Use print(count_ways(5)) to display the number of ways to climb a staircase with 5 steps.
DSA Python
Hint
Call the function with 5 and print the result to see how many ways there are.
Practice
(1/5)
1. What is the main purpose of using memoization in recursive functions?
easy
A. To replace recursion with iteration
B. To make the function run slower by adding extra steps
C. To store results of expensive function calls and reuse them
D. To increase the memory usage without any benefit
Solution
Step 1: Understand what memoization does
Memoization saves the results of function calls so that if the same inputs occur again, the function can return the saved result instead of recalculating.
Step 2: Identify the benefit of memoization
This saves time by avoiding repeated calculations, making recursive functions faster.
Final Answer:
To store results of expensive function calls and reuse them -> Option C
Quick Check:
Memoization = Store and reuse results [OK]
Hint: Memoization saves repeated work by caching results [OK]
Common Mistakes:
Thinking memoization slows down the function
Confusing memoization with converting recursion to loops
Believing memoization always increases memory without benefit
2. Which of the following is the correct way to define a memo dictionary inside a recursive function in Python?
easy
A. def fib(n, memo={}):
B. def fib(n, memo=None): memo = {}
C. def fib(n, memo=[]):
D. def fib(n, memo=0):
Solution
Step 1: Understand default mutable arguments problem
Using a mutable default argument like a dictionary directly can cause unexpected behavior because the same dictionary is shared across calls.
Step 2: Use None as default and initialize inside
Setting memo=None and then initializing memo = {} inside the function avoids this problem and is the correct pattern.
Final Answer:
def fib(n, memo=None): memo = {} -> Option B
Quick Check:
Use None default and initialize dict inside [OK]
Hint: Use None default and create dict inside function [OK]
Common Mistakes:
Using mutable default arguments directly
Using list instead of dictionary for memo
Setting memo default to 0 which is invalid
3. What will be the output of the following code?
def fib(n, memo=None):
if memo is None:
memo = {}
if n in memo:
return memo[n]
if n <= 1:
return n
memo[n] = fib(n-1, memo) + fib(n-2, memo)
return memo[n]
print(fib(5))
medium
A. 8
B. None
C. 3
D. 5
Solution
Step 1: Trace fib(5) with memoization
fib(5) = fib(4) + fib(3), fib(4) = fib(3) + fib(2), and so on. Using memoization avoids repeated calls.
Hint: Remember fib(5) = 5 in Fibonacci sequence [OK]
Common Mistakes:
Confusing fib(5) with fib(6)
Ignoring memo and recalculating values
Returning None due to missing return
4. Identify the error in this memoized factorial function and select the fix:
def factorial(n, memo=None):
if memo is None:
memo = {}
if n == 0:
return 1
if n in memo:
return memo[n]
memo[n] = n * factorial(n-1)
return memo[n]
medium
A. Add memo argument in recursive call: factorial(n-1, memo)
B. Change base case to n == 1
C. Initialize memo as a list instead of dict
D. Remove memo dictionary completely
Solution
Step 1: Check recursive call parameters
The recursive call factorial(n-1) misses passing memo, so memo is reset each time, losing stored results.
Step 2: Fix by passing memo in recursive call
Change to factorial(n-1, memo) to keep using the same memo dictionary.
Final Answer:
Add memo argument in recursive call: factorial(n-1, memo) -> Option A
Quick Check:
Pass memo in recursion to keep cache [OK]
Hint: Always pass memo in recursive calls [OK]
Common Mistakes:
Forgetting to pass memo in recursive call
Changing base case unnecessarily
Using list instead of dictionary for memo
5. You want to optimize a recursive function that calculates the number of ways to climb n stairs, taking 1 or 2 steps at a time. Which memoization approach below correctly avoids redundant calculations and handles edge cases?
hard
A. Use memo=None default, initialize inside, pass memo in recursive calls, and handle base cases for n=0 and n=1
B. Use a default mutable argument dictionary and update it inside the function
C. Do not use memoization; rely on simple recursion for clarity
D. Use a global dictionary outside the function to store results and pass n only
Solution
Step 1: Understand memoization best practice
Using memo=None default and initializing inside avoids shared mutable defaults and ensures fresh memo per call.
Step 2: Pass memo in recursive calls and handle base cases
Passing memo keeps cache consistent. Base cases n=0 (1 way) and n=1 (1 way) prevent infinite recursion and define correct results.
Final Answer:
Use memo=None default, initialize inside, pass memo in recursion, handle base cases -> Option A
Quick Check:
Proper memo init and passing + base cases = correct [OK]
Hint: Initialize memo inside and pass it in recursion [OK]
Common Mistakes:
Using global variables causing side effects
Using mutable default arguments directly
Ignoring base cases causing infinite recursion
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.