Skip to content

Commit d32e63d

Browse files
committed
LeetCode problem: 509. Fibonacci Number
1 parent 16aa638 commit d32e63d

File tree

3 files changed

+197
-0
lines changed

3 files changed

+197
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# 509. Fibonacci Number
2+
3+
Difficulty: `Easy`
4+
Topics: `Math`, `Dynamic Programming`, `Recursion`, `Memoization`
5+
6+
The **Fibonacci numbers**, commonly denoted `F(n)` form a sequence, called the **Fibonacci sequence**, such that each
7+
number is the sum of the two preceding ones, starting from `0` and `1`. That is,
8+
9+
```text
10+
F(0) = 0, F(1) = 1
11+
F(n) = F(n - 1) + F(n - 2), for n > 1.
12+
```
13+
14+
Given `n`, calculate `F(n)`.
15+
16+
**Example 1:**
17+
18+
```text
19+
Input: n = 2
20+
Output: 1
21+
Explanation: F(2) = F(1) + F(0) = 1 + 0 = 1.
22+
```
23+
24+
**Example 2:**
25+
26+
```text
27+
Input: n = 3
28+
Output: 2
29+
Explanation: F(3) = F(2) + F(1) = 1 + 1 = 2.
30+
```
31+
32+
**Example 3:**
33+
34+
```text
35+
Input: n = 4
36+
Output: 3
37+
Explanation: F(4) = F(3) + F(2) = 2 + 1 = 3.
38+
```
39+
40+
**Constraints:**
41+
42+
- `0 <= n <= 30`
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.bl.fibonacci_number;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
/**
7+
* This is the solution to the LeetCode problem: 509. Fibonacci Number
8+
*
9+
* @author Børre A. Opedal Lunde
10+
* @since 2024.01.27
11+
*/
12+
public class Solution {
13+
14+
// The cache of Fibonacci numbers.
15+
private static final List<Integer> FIBONACCI_NUMBERS_CACHE = new ArrayList<>();
16+
17+
// Initialize the cache with the two first Fibonacci numbers.
18+
static {
19+
FIBONACCI_NUMBERS_CACHE.add(0);
20+
FIBONACCI_NUMBERS_CACHE.add(1);
21+
}
22+
23+
public int fib(int n) {
24+
25+
final int fibonacciNumber;
26+
final int lastCachedFibonacciNumberIndex = FIBONACCI_NUMBERS_CACHE.size() - 1;
27+
28+
// Check if the Fibonacci number is already cached.
29+
if (n <= lastCachedFibonacciNumberIndex) {
30+
31+
// Retrieve the Fibonacci number from the cache.
32+
fibonacciNumber = FIBONACCI_NUMBERS_CACHE.get(n);
33+
34+
// Return the Fibonacci number.
35+
return fibonacciNumber;
36+
}
37+
38+
// If the Fibonacci number is not in the cache, let's start from where
39+
// we left off and put it there.
40+
41+
// Retrieve the two last Fibonacci numbers from the cache.
42+
final int a = FIBONACCI_NUMBERS_CACHE.get(lastCachedFibonacciNumberIndex - 1);
43+
final int b = FIBONACCI_NUMBERS_CACHE.get(lastCachedFibonacciNumberIndex);
44+
45+
// Calculate the Fibonacci number.
46+
fibonacciNumber = a + b;
47+
48+
// Add the Fibonacci number to the cache.
49+
FIBONACCI_NUMBERS_CACHE.add(fibonacciNumber);
50+
51+
// Check if we have reached the Fibonacci number we are looking for.
52+
if (n - 1 == lastCachedFibonacciNumberIndex) {
53+
return fibonacciNumber;
54+
}
55+
56+
// If not, let's continue recursively until we reach it.
57+
return fib(n);
58+
}
59+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.bl.fibonacci_number;
2+
3+
import org.junit.jupiter.api.DisplayName;
4+
import org.junit.jupiter.api.Test;
5+
import org.junit.jupiter.params.ParameterizedTest;
6+
import org.junit.jupiter.params.provider.Arguments;
7+
import org.junit.jupiter.params.provider.MethodSource;
8+
9+
import java.util.stream.Stream;
10+
11+
import static org.junit.jupiter.api.Assertions.assertEquals;
12+
13+
/**
14+
* This is the test to the LeetCode problem: 509. Fibonacci Number
15+
*
16+
* @author Børre A. Opedal Lunde
17+
* @since 2024.01.27
18+
*/
19+
@DisplayName("Fibonacci Number")
20+
class SolutionTest {
21+
22+
final Solution solution = new Solution();
23+
24+
@Test
25+
@DisplayName("Example one")
26+
void exampleOne() {
27+
int n = 2;
28+
int expected = 1;
29+
int actual = solution.fib(n);
30+
assertEquals(expected, actual);
31+
}
32+
33+
@Test
34+
@DisplayName("Example two")
35+
void exampleTwo() {
36+
int n = 3;
37+
int expected = 2;
38+
int actual = solution.fib(n);
39+
assertEquals(expected, actual);
40+
}
41+
42+
@Test
43+
@DisplayName("Example three")
44+
void exampleThree() {
45+
int n = 4;
46+
int expected = 3;
47+
int actual = solution.fib(n);
48+
assertEquals(expected, actual);
49+
}
50+
51+
static Stream<Arguments> provideFibonacciNumbersFromZeroToThirty() {
52+
return Stream.of(
53+
Arguments.of(0, 0),
54+
Arguments.of(1, 1),
55+
Arguments.of(2, 1),
56+
Arguments.of(3, 2),
57+
Arguments.of(4, 3),
58+
Arguments.of(5, 5),
59+
Arguments.of(6, 8),
60+
Arguments.of(7, 13),
61+
Arguments.of(8, 21),
62+
Arguments.of(9, 34),
63+
Arguments.of(10, 55),
64+
Arguments.of(11, 89),
65+
Arguments.of(12, 144),
66+
Arguments.of(13, 233),
67+
Arguments.of(14, 377),
68+
Arguments.of(15, 610),
69+
Arguments.of(16, 987),
70+
Arguments.of(17, 1597),
71+
Arguments.of(18, 2584),
72+
Arguments.of(19, 4181),
73+
Arguments.of(20, 6765),
74+
Arguments.of(21, 10946),
75+
Arguments.of(22, 17711),
76+
Arguments.of(23, 28657),
77+
Arguments.of(24, 46368),
78+
Arguments.of(25, 75025),
79+
Arguments.of(26, 121393),
80+
Arguments.of(27, 196418),
81+
Arguments.of(28, 317811),
82+
Arguments.of(29, 514229),
83+
Arguments.of(30, 832040)
84+
// Stop at 30 because the problem description
85+
// uses that as its upper limit.
86+
);
87+
}
88+
89+
@ParameterizedTest(name = "n {0} is Fibonacci number {1}")
90+
@DisplayName("Fibonacci numbers from zero to thirty")
91+
@MethodSource("provideFibonacciNumbersFromZeroToThirty")
92+
void fibonacciNumbersFromZeroToThirty(int n, int expected) {
93+
int actual = solution.fib(n);
94+
assertEquals(expected, actual);
95+
}
96+
}

0 commit comments

Comments
 (0)