Start learning free

LESSON 276 OF 410 · RECURSION

Recursion: Factorial in Python

Lesson O(n) Read the full explanation

In this video lesson we will learn about recursion, how recursive algorithms work and we will code a classic problem in recursive manner - Factorial:


Problem - Factorial:

Write a recursive function that given a non-negative integer n, returns the factorial of n, also denoted as n!

n! = 1 * 2 * 3 * ... * (n - 1) * n

Example:

Input: n = 5
Output: 120
Explanation: 5! = 1 * 2 * 3 * 4 * 5 = 120

Note:

Your algorithm should run in O(n) time and use O(n) extra space.


STEP 1 OF 2
    Ctrl + Enter to check

    PYTHON · RECURSION

    Recursion in Python, explained

    Introduction

    In this lesson, we will explore the concept of recursion and how it can be used to solve problems efficiently. Recursion is a fundamental programming technique where a function calls itself to solve smaller instances of the same problem. One classic example of a problem that can be solved using recursion is calculating the factorial of a number.

    Factorials are widely used in mathematics, particularly in combinatorics, algebra, and calculus. Understanding how to compute factorials recursively is a great way to grasp the basics of recursion, which is a powerful tool in a programmer's toolkit.

    Understanding the Basics

    Before diving into the recursive solution, let's understand the basic concept of a factorial. The factorial of a non-negative integer n, denoted as n!, is the product of all positive integers less than or equal to n. For example:

    • 0! = 1 (by definition)
    • 1! = 1
    • 2! = 2 * 1 = 2
    • 3! = 3 * 2 * 1 = 6
    • 4! = 4 * 3 * 2 * 1 = 24
    • 5! = 5 * 4 * 3 * 2 * 1 = 120

    Understanding these basics is crucial before moving on to the recursive approach.

    Main Concepts

    Recursion involves breaking down a problem into smaller sub-problems and solving each sub-problem recursively. For the factorial problem, the recursive approach can be defined as follows:

    • If n is 0, return 1 (base case).
    • Otherwise, return n multiplied by the factorial of n-1 (recursive case).

    This approach works because each call to the function reduces the problem size by 1, eventually reaching the base case.

    Examples and Use Cases

    Let's look at a few examples to understand how the recursive function works:

    Example 1:
    Input: n = 3
    Output: 6
    Explanation: 3! = 3 * 2 * 1 = 6
    
    Example 2:
    Input: n = 4
    Output: 24
    Explanation: 4! = 4 * 3 * 2 * 1 = 24
    

    In both examples, the function calls itself with a smaller value of n until it reaches the base case.

    Common Pitfalls and Best Practices

    When working with recursion, it's important to avoid common mistakes such as:

    • Not defining a base case, which can lead to infinite recursion.
    • Using too much memory due to deep recursion, which can cause a stack overflow.

    Best practices include:

    • Always defining a clear base case.
    • Ensuring that each recursive call progresses towards the base case.
    • Using iterative solutions for problems with very deep recursion to avoid stack overflow.

    Advanced Techniques

    For more advanced scenarios, you can optimize recursive solutions using techniques like memoization or dynamic programming. These techniques store the results of sub-problems to avoid redundant calculations and improve efficiency.

    Code Implementation

    Here is the Python code for the recursive factorial function:

    def factorial(n):
        # Base case: if n is 0, return 1
        if n == 0:
            return 1
        # Recursive case: return n * factorial(n-1)
        else:
            return n * factorial(n-1)
    
    # Example usage
    print(factorial(5))  # Output: 120
    

    This code defines a function factorial that computes the factorial of a given non-negative integer n using recursion.

    Debugging and Testing

    When debugging recursive functions, it's helpful to use print statements to trace the function calls. For example:

    def factorial(n):
        print(f"Calling factorial({n})")
        if n == 0:
            return 1
        else:
            result = n * factorial(n-1)
            print(f"Returning {result} for factorial({n})")
            return result
    
    # Example usage
    print(factorial(5))  # Output: 120
    

    To test the function, you can write test cases using a testing framework like unittest:

    import unittest
    
    class TestFactorial(unittest.TestCase):
        def test_factorial(self):
            self.assertEqual(factorial(0), 1)
            self.assertEqual(factorial(1), 1)
            self.assertEqual(factorial(2), 2)
            self.assertEqual(factorial(3), 6)
            self.assertEqual(factorial(4), 24)
            self.assertEqual(factorial(5), 120)
    
    if __name__ == '__main__':
        unittest.main()
    

    Thinking and Problem-Solving Tips

    When approaching recursive problems, consider the following strategies:

    • Identify the base case and ensure it is correctly implemented.
    • Break down the problem into smaller sub-problems that can be solved recursively.
    • Use diagrams or write out the recursive calls to visualize the process.
    • Practice with different problems to strengthen your understanding of recursion.

    Conclusion

    In this lesson, we explored the concept of recursion and how to use it to solve the factorial problem. Recursion is a powerful technique that can simplify complex problems by breaking them down into smaller, more manageable parts. By mastering recursion, you can tackle a wide range of problems in programming.

    Remember to practice and apply these concepts to different problems to deepen your understanding and improve your problem-solving skills.

    Additional Resources

    For further reading and practice, consider the following resources:

    Keep going with PythonAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free