Problem overview
The Fibonacci numbers start with F(0) = 0 and F(1) = 1, and every later number is the sum of the two before it: F(n) = F(n - 1) + F(n - 2). The sequence begins 0, 1, 1, 2, 3, 5, 8, 13, and so on.
The lesson asks for a recursive method, int Fibonacci(int n), that returns F(n) for 0 <= n <= 30. For n = 4 the answer is 3, because F(4) = F(3) + F(2) = 2 + 1.
The definition is already recursive, so the code can follow it almost word for word. The lesson says not to worry about time and space, which makes this a good first look at a method that calls itself twice.
Approach: turn the definition into code
A recursive method needs a base case that stops the calls and a recursive case that moves toward it. Fibonacci has two starting values, so its base case covers both. For n = 0 the answer is 0, and for n = 1 it is 1. In both cases the answer equals n, so a single check for n < 2 that returns n handles them together.
For any larger n, return Fibonacci(n - 1) + Fibonacci(n - 2). Both calls use smaller arguments, so every chain of calls ends at a base case.
Step by step
- Handle the base case first. If
n < 2, returnn. Without it, the calls would go on toFibonacci(-1),Fibonacci(-2)and further, never stopping. - Return the sum of the two previous numbers:
Fibonacci(n - 1) + Fibonacci(n - 2).
The solution in C#
class Solution {
public int Fibonacci(int n) {
if (n < 2) {
return n;
}
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
}
How the calls unfold
Here is Fibonacci(4), written as a tree where each line is one call:
Fibonacci(4)
Fibonacci(3)
Fibonacci(2)
Fibonacci(1) -> 1
Fibonacci(0) -> 0
Fibonacci(1) -> 1
Fibonacci(2)
Fibonacci(1) -> 1
Fibonacci(0) -> 0
Working upward: Fibonacci(2) is 1 + 0 = 1, Fibonacci(3) is 1 + 1 = 2, and the second Fibonacci(2) is 1 again. So Fibonacci(4) is 2 + 1 = 3. This tree makes 9 calls in total.
Notice that Fibonacci(2) is computed twice, and Fibonacci(1) three times. The method has no memory of earlier answers, so the same work repeats. The repeats multiply as n grows. Computing Fibonacci(30), which is 832040, takes 2,692,537 calls. That is fine for this lesson, whose input stops at 30, but the call count grows exponentially, and each step of n multiplies the work by about 1.6. Remembering results already computed, called memoization, or building the sequence upward in a loop, brings the cost down to linear time.
C# details worth knowing
- The result fits in an
int.F(30) = 832040, far below 2,147,483,647. In C#,intoverflow wraps silently, so with larger inputs the sums would turn wrong without any error.F(46)is the last Fibonacci number that fits in anint. - Two calls in one expression. The expression
Fibonacci(n - 1) + Fibonacci(n - 2)evaluates its left operand first, so the left chain of calls runs to completion before the right one starts. - Depth is small. The call stack gets as deep as
nframes, because then - 1branch goes down first. That is nothing to worry about forn <= 30. - Names. The method is
Fibonacci, in PascalCase. A call spelledfibonacciwould not compile in C#.
Edge cases and common mistakes
- Checking only
n == 0. ThenFibonacci(1)callsFibonacci(0)andFibonacci(-1), and the second call never reaches the base case. Both starting values need to be covered, whichn < 2does. - Returning
1for the base case. That gives the wrong value forn = 0. Returningnis correct for both starting values. - Calling
Fibonacci(n - 1)twice or mixing upn - 2andn - 1in the sum. The two terms must be the previous two numbers. - Expecting speed. This version is simple, not fast. Do not use it for much larger
n.
Testing
| n | result |
|---|---|
0 | 0 |
1 | 1 |
2 | 1 |
3 | 2 |
4 | 3 |
10 | 55 |