Recursion Concept and Call Stack Visualization in DSA Python - Time & Space Complexity
When we use recursion, the function calls itself to solve smaller parts of a problem.
We want to know how the number of these calls grows as the input gets bigger.
Analyze the time complexity of the following code snippet.
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n - 1)
This code calculates the factorial of a number using recursion by calling itself with smaller values.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The recursive call to
factorial(n - 1). - How many times: It repeats once for each number from
ndown to 1, sontimes.
Each time we call the function, it calls itself once with a smaller number until it reaches zero.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 calls |
| 100 | About 100 calls |
| 1000 | About 1000 calls |
Pattern observation: The number of calls grows directly with the input size; doubling n doubles the calls.
Time Complexity: O(n)
This means the time it takes grows in a straight line with the size of the input number.
[X] Wrong: "Recursion always makes the program slow and complicated."
[OK] Correct: Simple recursion like this runs in linear time and is easy to understand; it's not always slow or complex.
Understanding how recursion grows helps you explain your solutions clearly and shows you can think about how code performs as inputs get bigger.
"What if we changed the recursion to call itself twice each time, like in a Fibonacci sequence? How would the time complexity change?"
Practice
def recurse():
recurse()
Solution
Step 1: Understand recursion definition
Recursion is when a function calls itself to break down a problem into smaller parts.Step 2: Match with options
A function calling itself to solve smaller parts of a problem correctly describes recursion as self-calling function for smaller problems.Final Answer:
A function calling itself to solve smaller parts of a problem -> Option AQuick Check:
Recursion = self-calling function [OK]
- Confusing recursion with infinite loops
- Thinking recursion is just a loop
- Believing recursion stores data like lists
Solution
Step 1: Check function syntax for recursion
A recursive function must call itself. It does not always require a return statement unless the return value is used.Step 2: Analyze options
def recurse(): recurse() correctly defines a recursive function that calls itself.Final Answer:
def recurse(): recurse() -> Option AQuick Check:
Recursive call without return is valid syntax [OK]
- Missing recursive call
- Incorrect use of return
- Confusing print statement with recursion
def countdown(n):
if n == 0:
return 'Done'
else:
print(n)
return countdown(n-1)
countdown(3)Solution
Step 1: Trace recursive calls and prints
Function prints n then calls countdown(n-1) until n=0, then returns 'Done'. So prints 3, 2, 1 in order.Step 2: Understand return value and print output
Only numbers 3, 2, 1 are printed. 'Done' is returned but not printed, so output shows numbers only.Final Answer:
3 2 1 -> Option CQuick Check:
Prints countdown down to 1 then returns 'Done' [OK]
- Thinking 'Done' is printed automatically
- Confusing order of printed numbers
- Ignoring base case return
def sum_to_n(n):
if n == 1:
return 1
else:
return n + sum_to_n(n)
print(sum_to_n(3))Solution
Step 1: Check recursive call parameter
Recursive call should reduce n by 1 to approach base case, but it calls sum_to_n(n) again causing infinite recursion.Step 2: Identify correct fix
Change recursive call to sum_to_n(n-1) to reduce n each time and reach base case.Final Answer:
Recursive call uses n instead of n-1 -> Option BQuick Check:
Recursive call must reduce n to avoid infinite loop [OK]
- Calling function with same argument causing infinite recursion
- Forgetting to reduce argument in recursion
- Confusing base case presence
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)
What is the call stack sequence when calling
factorial(3)?Solution
Step 1: Understand recursive calls order
factorial(3) calls factorial(2), which calls factorial(1), which calls factorial(0) base case.Step 2: Trace call stack sequence
Calls go down from 3 to 0 before returning results back up the stack.Final Answer:
factorial(3) -> factorial(2) -> factorial(1) -> factorial(0) -> Option DQuick Check:
Recursive calls descend to base case 0 [OK]
- Thinking calls go from base case up
- Repeating same call multiple times
- Skipping base case call
Ready to prove it?
Pass the test and this pattern moves unknown
