Factorial Using Recursion in DSA Rust - Time & Space Complexity
We want to understand how the time to calculate a factorial grows as the input number gets bigger.
Specifically, how many steps does the recursive factorial function take as the input increases?
Analyze the time complexity of the following code snippet.
fn factorial(n: u32) -> u32 {
if n == 0 {
1
} else {
n * factorial(n - 1)
}
}
This code calculates the factorial of a number using recursion by multiplying the number by the factorial of one less than it, until it reaches zero.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Recursive call to factorial with n-1
- How many times: Exactly n + 1 times until it reaches 0
Each time we call factorial, it calls itself once with a smaller number until it reaches zero.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 11 recursive calls |
| 100 | 101 recursive calls |
| 1000 | 1001 recursive calls |
Pattern observation: The number of steps grows directly with the input size; doubling n doubles the work.
Time Complexity: O(n)
This means the time to compute factorial grows linearly with the input number.
[X] Wrong: "Recursion makes factorial calculation take exponential time because it calls itself multiple times."
[OK] Correct: Each call only makes one recursive call, so the total calls equal n + 1, not more. It is a simple chain, not a tree of calls.
Understanding how recursion affects time helps you explain and write efficient code clearly in interviews.
"What if we changed the recursion to use memoization? How would the time complexity change?"
Practice
Solution
Step 1: Understand factorial definition
Factorial of a number n (written as n!) is the product of all positive integers from 1 to n.Step 2: Compare options
Only The product of all positive integers up to that number correctly describes factorial as a product, not sum or division.Final Answer:
The product of all positive integers up to that number -> Option DQuick Check:
Factorial = product of integers [OK]
- Confusing factorial with sum
- Thinking factorial divides the number
- Assuming factorial doubles the number
Solution
Step 1: Identify input and output types
Factorial takes a positive integer (u32) and returns a positive integer (u32).Step 2: Match function signature
fn factorial(n: u32) -> u32 matches input and output types correctly for factorial.Final Answer:
fn factorial(n: u32) -> u32 -> Option CQuick Check:
Input and output types match factorial [OK]
- Using String type for input or output
- Using signed integer when unsigned is better
- Returning bool instead of number
fn factorial(n: u32) -> u32 {
if n == 0 { 1 } else { n * factorial(n - 1) }
}
fn main() {
println!("{}", factorial(4));
}Solution
Step 1: Trace recursive calls for factorial(4)
factorial(4) = 4 * factorial(3) factorial(3) = 3 * factorial(2) factorial(2) = 2 * factorial(1) factorial(1) = 1 * factorial(0) factorial(0) = 1 (base case)Step 2: Calculate values bottom-up
factorial(1) = 1 * 1 = 1 factorial(2) = 2 * 1 = 2 factorial(3) = 3 * 2 = 6 factorial(4) = 4 * 6 = 24Final Answer:
24 -> Option BQuick Check:
4! = 24 [OK]
- Confusing factorial with sum
- Forgetting base case returns 1
- Multiplying incorrectly in recursion
fn factorial(n: u32) -> u32 {
if n == 1 { 1 } else { n * factorial(n - 1) }
}Solution
Step 1: Check base case correctness
Factorial base case is when n == 0, factorial(0) = 1. Using n == 1 misses factorial(0).Step 2: Understand recursion impact
If base case is n == 1, factorial(0) call will recurse infinitely causing stack overflow.Final Answer:
Base case should be n == 0, not n == 1 -> Option AQuick Check:
Base case at zero prevents infinite recursion [OK]
- Setting base case at 1 instead of 0
- Changing recursion direction incorrectly
- Ignoring missing semicolons (Rust warns)
Solution
Step 1: Understand overflow in factorial
Factorial grows very fast; u32 overflows quickly. Using u128 allows larger values.Step 2: Add input range check
To prevent overflow, check input is within safe range before calculation.Final Answer:
Use u128 type and add a check for input range to avoid overflow -> Option AQuick Check:
Use larger integer type and validate input [OK]
- Using signed integers causing negative overflow
- Using floating-point loses precision
- Ignoring overflow checks
Ready to prove it?
Pass the test and this pattern moves unknown
