← Back to DSA Course | Chapter 8: Recursion & Backtracking | Lesson 2 of 7

Fibonacci and Factorial

Factorial

The factorial of n (written n!) is the product of every positive integer up to n, and it's usually the very first example used to teach recursion because its recursive definition (n! = n times (n-1)!) mirrors the code almost exactly.

Example: Factorial

#include <iostream>
using namespace std;
int factorial(int n) {
	if (n <= 1) return 1;
	return n * factorial(n - 1);
}
int main() {
	cout << factorial(5);
	return 0;
}
public class Main {
	static int factorial(int n) {
		if (n <= 1) return 1;
		return n * factorial(n - 1);
	}
	public static void main(String[] args) {
		System.out.println(factorial(5));
	}
}
def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)

print(factorial(5))
#include <stdio.h>
int factorial(int n) {
	if (n <= 1) return 1;
	return n * factorial(n - 1);
}
int main() {
	printf("%d", factorial(5));
	return 0;
}

Fibonacci

The Fibonacci sequence defines each number as the sum of the two before it (0, 1, 1, 2, 3, 5, 8...), making it a natural second recursion example since, unlike factorial, it needs two recursive calls per step instead of one.

Example: Fibonacci

#include <iostream>
using namespace std;
int fib(int n) {
	if (n <= 1) return n;
	return fib(n - 1) + fib(n - 2);
}
int main() {
	cout << fib(7);
	return 0;
}
public class Main {
	static int fib(int n) {
		if (n <= 1) return n;
		return fib(n - 1) + fib(n - 2);
	}
	public static void main(String[] args) {
		System.out.println(fib(7));
	}
}
def fib(n):
    if n <= 1:
        return n
    return fib(n - 1) + fib(n - 2)

print(fib(7))
#include <stdio.h>
int fib(int n) {
	if (n <= 1) return n;
	return fib(n - 1) + fib(n - 2);
}
int main() {
	printf("%d", fib(7));
	return 0;
}

Recursive Comparison

Factorial recursion is linear — each call makes exactly one further call, so the total work grows proportionally with n. Fibonacci's naive recursion branches into two calls at every step, so its total work grows exponentially even though the final numbers are simple.

Example: Recursive Comparison

#include <iostream>
using namespace std;
int calls = 0;
int fib(int n) {
	calls++;
	if (n <= 1) return n;
	return fib(n - 1) + fib(n - 2);
}
int main() {
	fib(10);
	cout << "calls: " << calls;
	return 0;
}
public class Main {
	static int calls = 0;
	static int fib(int n) {
		calls++;
		if (n <= 1) return n;
		return fib(n - 1) + fib(n - 2);
	}
	public static void main(String[] args) {
		fib(10);
		System.out.println("calls: " + calls);
	}
}
calls = 0
def fib(n):
    global calls
    calls += 1
    if n <= 1:
        return n
    return fib(n - 1) + fib(n - 2)

fib(10)
print("calls:", calls)
#include <stdio.h>
int calls = 0;
int fib(int n) {
	calls++;
	if (n <= 1) return n;
	return fib(n - 1) + fib(n - 2);
}
int main() {
	fib(10);
	printf("calls: %d", calls);
	return 0;
}

Memoization Idea

Because naive recursive Fibonacci recomputes the same smaller values over and over, storing already-computed results (memoization) avoids that repeated work and brings the running time down from exponential to linear.

Example: Memoization Idea

#include <iostream>
#include <unordered_map>
using namespace std;
unordered_map<int, int> memo;
int fib(int n) {
	if (n <= 1) return n;
	if (memo.count(n)) return memo[n];
	return memo[n] = fib(n - 1) + fib(n - 2);
}
int main() {
	cout << fib(30);
	return 0;
}
import java.util.*;
public class Main {
	static HashMap<Integer, Integer> memo = new HashMap<>();
	static int fib(int n) {
		if (n <= 1) return n;
		if (memo.containsKey(n)) return memo.get(n);
		int result = fib(n - 1) + fib(n - 2);
		memo.put(n, result);
		return result;
	}
	public static void main(String[] args) {
		System.out.println(fib(30));
	}
}
memo = {}
def fib(n):
    if n <= 1:
        return n
    if n in memo:
        return memo[n]
    memo[n] = fib(n - 1) + fib(n - 2)
    return memo[n]

print(fib(30))
#include <stdio.h>
long memo[40] = {0};
long fib(int n) {
	if (n <= 1) return n;
	if (memo[n]) return memo[n];
	return memo[n] = fib(n - 1) + fib(n - 2);
}
int main() {
	printf("%ld", fib(30));
	return 0;
}

Practice

Working through both problems by hand — tracing the call stack for factorial and drawing the branching call tree for Fibonacci — builds the intuition needed for harder recursive and dynamic programming problems later on.

Example: Practice

#include <iostream>
using namespace std;
int factorial(int n) { return n <= 1 ? 1 : n * factorial(n - 1); }
int fib(int n) { return n <= 1 ? n : fib(n - 1) + fib(n - 2); }
int main() {
	cout << "5! = " << factorial(5) << ", fib(6) = " << fib(6);
	return 0;
}
public class Main {
	static int factorial(int n) { return n <= 1 ? 1 : n * factorial(n - 1); }
	static int fib(int n) { return n <= 1 ? n : fib(n - 1) + fib(n - 2); }
	public static void main(String[] args) {
		System.out.println("5! = " + factorial(5) + ", fib(6) = " + fib(6));
	}
}
def factorial(n):
    return 1 if n <= 1 else n * factorial(n - 1)

def fib(n):
    return n if n <= 1 else fib(n - 1) + fib(n - 2)

print("5! =", factorial(5), ", fib(6) =", fib(6))
#include <stdio.h>
int factorial(int n) { return n <= 1 ? 1 : n * factorial(n - 1); }
int fib(int n) { return n <= 1 ? n : fib(n - 1) + fib(n - 2); }
int main() {
	printf("5! = %d, fib(6) = %d", factorial(5), fib(6));
	return 0;
}
🔒

Chapter Quiz — Complete all 7 topics to unlock

0/7 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.