📖 Scenario: Imagine you are helping a friend calculate the number of ways to climb stairs. Each time, they can climb either 1 or 2 steps. You want to write a program that quickly finds the number of ways to reach the top of a staircase with a given number of steps.
🎯 Goal: Build a Go program that uses memoization to optimize a recursive function calculating the number of ways to climb stairs.
📋 What You'll Learn
Create a map called memo to store intermediate results.
Write a recursive function climbWays that takes an integer n and returns the number of ways to climb n steps.
Use memoization inside climbWays to avoid repeated calculations.
Print the number of ways to climb 10 steps.
💡 Why This Matters
🌍 Real World
Memoization helps speed up programs that solve problems with overlapping subproblems, like calculating Fibonacci numbers or counting ways to climb stairs.
💼 Career
Understanding memoization is important for software developers to write efficient recursive algorithms and optimize performance in real-world applications.
Progress0 / 4 steps
1
Create the memo map
Create a variable called memo as a map from int to int to store results of previous calculations.
DSA Go
Hint
Use make(map[int]int) to create an empty map for memoization.
2
Add the climbWays function
Add a recursive function called climbWays that takes an integer n and a map memo of type map[int]int. The function should return an int.
DSA Go
Hint
Use base case n <= 1 returning 1. Check if n is in memo. If yes, return it. Otherwise, calculate recursively and store in memo.
3
Call climbWays for 10 steps
Inside main, call climbWays with n = 10 and the memo map. Store the result in a variable called result.
DSA Go
Hint
Call climbWays(10, memo) and save the answer in result.
4
Print the result
Print the value of result using fmt.Println inside main.
DSA Go
Hint
Use fmt.Println(result) to show the number of ways to climb 10 steps.
Practice
(1/5)
1. What is the main purpose of memoization in recursive functions?
easy
A. To store results of expensive function calls and reuse them
B. To make the function run slower by adding extra steps
C. To remove recursion and use loops instead
D. To increase the memory usage without any benefit
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 of memoization
By reusing saved results, the function runs faster and avoids repeated work.
Final Answer:
To store results of expensive function calls and reuse them -> Option A
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 removing recursion
Ignoring the memory benefit of caching
2. Which of the following Go code snippets correctly declares a memo map for memoization of integer keys and values?
easy
A. memo := new(map[int]int)
B. memo := make(map[int]int)
C. memo := make([]int, 10)
D. memo := map[string]int{}
Solution
Step 1: Identify correct map declaration syntax
In Go, make(map[int]int) creates a map with int keys and int values.
Step 2: Check other options
memo := map[string]int{} uses string keys, not int; memo := make([]int, 10) creates a slice, not a map; memo := new(map[int]int) creates a pointer to a map but does not initialize it.
Final Answer:
memo := make(map[int]int) -> Option B
Quick Check:
Correct map syntax = make(map[int]int) [OK]
Hint: Use make(map[int]int) to create int-to-int map [OK]
Common Mistakes:
Using slice instead of map for memo
Using wrong key type in map
Declaring pointer to map without initialization
3. What will be the output of the following Go code using memoization for Fibonacci numbers?
package main
import "fmt"
func fib(n int, memo map[int]int) int {
if n <= 1 {
return n
}
if val, ok := memo[n]; ok {
return val
}
memo[n] = fib(n-1, memo) + fib(n-2, memo)
return memo[n]
}
func main() {
memo := make(map[int]int)
fmt.Println(fib(5, memo))
}
medium
A. 8
B. Error
C. 3
D. 5
Solution
Step 1: Understand Fibonacci calculation with memo
fib(5) = fib(4) + fib(3), and memo stores intermediate results to avoid repeats.
4. Identify the error in this Go recursive function with memoization for factorial:
func fact(n int, memo map[int]int) int {
if n == 0 {
return 1
}
if val, ok := memo[n]; ok {
return val
}
memo[n] = n * fact(n-1, memo)
return memo[n]
}
func main() {
memo := make(map[int]int)
fmt.Println(fact(-1, memo))
}
medium
A. Compilation error due to map usage
B. No error, output is 1
C. Infinite recursion for negative input
D. Returns 0 for negative input
Solution
Step 1: Analyze base case and input
Base case is n == 0, but input is -1, so base case never reached.
Step 2: Understand recursion behavior
For n = -1, function calls fact(-2), then fact(-3), causing infinite recursion.
Final Answer:
Infinite recursion for negative input -> Option C
Quick Check:
Negative input causes infinite recursion [OK]
Hint: Check base case covers all inputs to avoid infinite recursion [OK]
Common Mistakes:
Assuming negative input returns 1
Ignoring infinite recursion possibility
Expecting compilation error incorrectly
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 using memoization in Go. Which approach below correctly applies memoization to avoid repeated calculations?
hard
A. Pass a map[int]int as a parameter to the function and store intermediate results in it
B. Use a slice of size n and fill it after recursion completes
C. Use a global variable to store results and update it inside the function
D. Call the recursive function twice without storing results
Solution
Step 1: Understand memoization with parameters
Passing a map as a parameter allows storing and reusing results during recursion.
Step 2: Evaluate options for memoization
Pass a map[int]int as a parameter to the function and store intermediate results in it correctly uses a map parameter; Use a global variable to store results and update it inside the function uses global state which is less safe; Use a slice of size n and fill it after recursion completes fills after recursion, not during; Call the recursive function twice without storing results repeats work without memo.
Final Answer:
Pass a map[int]int as a parameter to the function and store intermediate results in it -> Option A