Introduction
Welcome back! In our last few lessons, we've focused on analyzing algorithm efficiency by calculating and comparing different Big-O complexity classes. This helps us evaluate an existing algorithm. Today, we shift gears to a powerful technique for designing algorithms: recursion.
Your goal for this lesson is to learn how to formulate base cases and recursive steps to solve simple problems recursively, using factorial as a key example. Recursion is a fundamental concept in computer science and a cornerstone of solutions for more complex topics you'll face in interviews, such as tree traversals, graph searches, and dynamic programming. Mastering the basics here will pay significant dividends later.
The Two Pillars of Recursion
At its core, a recursive algorithm is one that solves a problem by calling itself with a smaller version of the same problem. To avoid an infinite loop (like shampoo instructions to "lather, rinse, repeat"), a recursive function needs two essential components.
Introduction to Recursion - GeeksforGeeks
This article provides a concise definition of the two critical parts of any recursive solution: the base case and the recursive case.
Read the 'Steps to Implement Recursion' section. Focus on understanding the definitions of 'Step 1 - Define a base case' and 'Step 2 - Define a recursive case'.
To summarize the key ideas from the reading:
- Base Case: The simplest possible version of the problem, which can be solved directly without making another recursive call. This is the stopping condition.
- Recursive Step: The part of the function that breaks the problem down into a smaller piece and calls itself on that smaller piece. This step must make progress toward reaching the base case.
How Does Recursion Actually Work? The Call Stack
When a function calls itself, how does the computer keep track of everything? It uses a structure you'll learn more about later: the stack. Each time the function is called, a new "frame" is pushed onto the call stack to store its local variables and its current place in the execution. When a function finishes (i.e., hits a base case and returns), its frame is popped off the stack, and control returns to the function below it.
A stack overflow error, which you may have encountered, happens when the recursive calls go too deep without hitting a base case, and the computer runs out of memory for the call stack.

A Framework for Solving Recursive Problems
Thinking recursively can feel unnatural at first. Instead of thinking step-by-step (iteratively), you need to think about the problem in terms of self-similarity. The following video introduces a brilliant 5-step framework that turns this abstract idea into a concrete, repeatable process—perfect for interviews.
5 Simple Steps for Solving Any Recursive Problem
This video from Reducible presents a clear, actionable framework for tackling any recursive problem. We'll focus on how it applies this framework to a simple problem.
Watch from the beginning to 06:17. Pay close attention to the five steps introduced and how they are used to solve the problem of summing integers up to 'n'. Also, note the concept of the 'recursive leap of faith'—it's a key mental trick for trusting your recursive function to work on smaller inputs.
The five steps are:
- Find the simplest possible input (this will be your base case).
- Play with examples and visualize to understand the problem.
- Relate larger examples to smaller examples (this helps you find the recursive step).
- Generalize the pattern into a recurrence relation.
- Write the code by combining the base case and the recursive step.
Applying the Framework: The Factorial Problem
Now, let's use this framework to solve the classic factorial problem, which is explicitly mentioned in our learning outcome. The factorial of a non-negative integer n, denoted by n!, is the product of all positive integers less than or equal to n. For example, 5! = 5 * 4 * 3 * 2 * 1 = 120.
-
Simplest Input (Base Case): What is the simplest factorial? By definition,
0! = 1. This is a perfect stopping condition. We can also use1! = 1. -
Relate Larger to Smaller: How can we define
5!using a smaller factorial?5! = 5 * (4 * 3 * 2 * 1)5! = 5 * 4!
-
Generalize the Pattern: This reveals the recurrence relation:
-
Write the Code: We combine the base case (
if n == 0, return 1) with the recursive step (return n * factorial(n-1)).
The following resource walks through this exact thought process.
.NET Developer Basics - Recursive Algorithms - Simple Talk
This article clearly shows how the mathematical definition of a factorial translates directly into a recursive function.
Read the section 'A Quick Dive into the Recursive Factorial Function'. Notice how the recurrence relation in 'Listing 12' directly maps to the final code in 'Listing 15'. The C# code is very similar to Java.
For a more detailed, code-centric walkthrough in Java, the next video is excellent. It explains how the values are returned up the call stack to compute the final result.
Recursion - Level 1 Questions (Theory + Code + Tips)
Let's watch a practical, code-focused explanation of the factorial function in Java.
Watch from 15:03 to 23:35. Pay attention to how the function returns a value at each step and how those returned values are used by the calling function higher up in the stack. This is a crucial concept for recursive functions that compute a value.
Here is a complete Java implementation based on what you've seen:
public class RecursionExample {
public static int factorial(int n) {
// Step 1: Base Case - The simplest problem we can solve directly.
if (n <= 1) {
return 1;
}
// Step 2: Recursive Step - Break the problem down and call itself.
// The 'recursive leap of faith': assume factorial(n-1) works correctly.
else {
return n * factorial(n - 1);
}
}
public static void main(String[] args) {
int number = 5;
int result = factorial(number);
System.out.println("The factorial of " + number + " is " + result); // Output: The factorial of 5 is 120
}
}
One More Practice Problem
Let's do one more quick problem to solidify the pattern. How would you find the sum of the digits of a number? For example, for 1342, the result is 1 + 3 + 4 + 2 = 10.
- Base Case: If the number is a single digit (or 0), the sum is the number itself. A simple base case is
if (n == 0) return 0;. - Recursive Step: The sum of digits of
1342can be seen as(the last digit) + (the sum of digits of the rest of the number).- Last digit:
1342 % 10 = 2 - Rest of the number:
1342 / 10 = 134 - Recurrence Relation:
sumDigits(n) = (n % 10) + sumDigits(n / 10)
- Last digit:
This video provides a clear Java implementation of this logic.
Recursion - Level 1 Questions (Theory + Code + Tips)
Let's see the 'sum of digits' problem solved recursively in Java.
Watch from 24:16 to 30:52. This is another perfect example of breaking a problem down using simple arithmetic (% and /) to fuel the recursion.
Conclusion
In this lesson, you took the first crucial step into the world of recursive problem-solving. While we focused on simple problems, the thought process you practiced is the same one you'll use for much harder interview questions.
Key Takeaways:
- Every recursive algorithm is built on two pillars: a base case to stop the recursion, and a recursive step to break the problem down.
- The call stack is the mechanism that manages memory for recursive function calls, pushing a new frame for each call and popping it upon return.
- You can approach any recursive problem systematically by identifying the simplest input (base case) and then finding the recurrence relation (recursive step) that relates a problem to a smaller version of itself.
- Taking the "recursive leap of faith"—trusting that your function will work for smaller inputs—is essential to avoid getting bogged down in the details of the call stack.
In our next lesson, we will wrap up our foundational module by discussing the time-space tradeoff. We'll see how recursion, while often elegant, comes with a space complexity cost due to the call stack, and we'll analyze the time complexity of the recursive functions we wrote today.