Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added fibonacci problem as dynamic programming example #167

Merged
merged 3 commits into from
Oct 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions Dynamic Programming/Fibonacci Sequence/Java/Fibonacci.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* The 3 general approaches to a very basic dynamic programming problem - the fibonacci sequence
*/
public class Fibonacci {

/**
* The very basic fibonacci sequence.
* Notice the run time is O(n^2) as it has to recalculate the same value numerous times.
* This is something we try to avoid.
*
* E.G) To get fib(4):
* fib(5)
* / \
* fib(3) fib(4)
* / \ / \
* fib(2) fib(1) fib(2) fib(3)
* / \
* fib(2) fib(1)
*
* @param n The nth fibonacci number
* @return The value of the nth fibonacci number
*/
public int naiveFibonacci(int n) {
assert n > 0;

if(n == 1 || n == 2)
return 1;

return naiveFibonacci(n-1) + naiveFibonacci(n-2);
}

private Map<Integer, Integer> memo = new HashMap<>();

/**
* Very similar to above but notice the reference to a map.
* This is a memo and keeps track of values we have already crossed.
* Since retrieval from a map is O(1) it improves the runtime of the program by not having to recalculate
* same values over and over.
*
* @param n The nth fibonacci number
* @return The value of the nth fibonacci number
*/
public int memoizedFibonacci(int n) {
assert n > 0;

if(n == 1 || n == 2)
return 1;

//If we already calculated the value before.
if(memo.containsKey(n))
return memo.get(n);

//If not, add it to the memo in case we need to retrieve it again
int fib = naiveFibonacci(n-1) + naiveFibonacci(n-2);
memo.put(n, fib);

return fib;
}

/**
* Now this is very different to the other two. No recursion, just a primitive array.
* How this works is based of how you look at fibonacci normally:
* 1,1,2,3,5,... The next number is the sum of the previous two - as can be seen in the for loop.
* The first two indexes represent the first and second value (hence why the if just returns 1 if you input a value
* less than 3).
* The runtime complexity is also easier as it become O(n) since we only pass the loop once and O(n) space as
* the array increases proportionally to the increase in input value n.
*
* @param n The nth fibonacci number
* @return The value of the nth fibonacci number
*/
public int tabulatedFibonacci(int n) {
assert n > 0;

if(n < 3)
return 1;

int[] tab = new int[n];
tab[0] = 1; tab[1] = 1;

for(int i=2; i<n; i++) {
tab[i] = tab[i-1] + tab[i-2];
}

return tab[n-1];
}
}
28 changes: 28 additions & 0 deletions Dynamic Programming/Fibonacci Sequence/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## Fibonacci

More on the history and explanation [here](https://en.wikipedia.org/wiki/Fibonacci_number).
In short, the fibonacci sequence is a list of ascending numbers in such a way that the
number at index n is the sum of n-1 and n-2.

### Example
the number at the _sixth_ index is __8__.<br>
This is because it is the sum of the 5th and 4th elements which are __5__ and __3__.
The full sequence leading up to it is:
```
1,1,2,3,5,8
```

A reminder that this is an infinite sequence therefore there is no end, but in programming
terms, end will be reached when it reaches max value (which in Java is 2^31 since int is 32 bit).

One question that may also be asked (along with the examples provided) is to get n-step fibonacci.
This refers to n numbers added to create the next digit.

### Example
3 step fibonacci (also called tribonacci) will look as follows:
```
1,1,2,4,7,13,24
```
As it is adding the 3 previous values before it. Note the _1,1,2_ as the third index only has two numbers
to use, it will only be able to add them.