Reputation: 153
I'm trying to learn Memoization of Dynamic Programming and I was watching video on youtube from MIT trying to follow along with it. I don't know how to compare the Nth value to an array.
int[] memo;
public int fib(int n) {
int f = 0;
if n is in memo then return memo[n] <----not sure how to code this line.
if (n<=2) {
f = 1;
} else {
f = fib(n-1) + fib(n-2);
}
memo[n] = f;
return f;
}
Upvotes: 1
Views: 1836
Reputation: 55589
Doing it with ArrayList
:
ArrayList<Integer> memo = new ArrayList<Integer>();
public int fib(int n) {
if (memo.size() == 0)
memo.add(0); // element 0 is never accessed
return fib2(n);
}
private int fib2(int n) {
int f = 0;
if (n < memo.size())
return memo.get(n);
if (n<=2) {
f = 1;
} else {
f = fib2(n-2) + fib2(n-1);
}
memo.add(f); // elements inserted in order
return f;
}
Doing it with array:
int[] memo;
public int fib(int n) {
memo = new int[n+1]; // all initialized to 0
return fib2(n);
}
private int fib2(int n) {
int f = 0;
if (memo[n] != 0)
return memo[n];
if (n <= 2) {
f = 1;
} else {
f = fib2(n-2) + fib2(n-1);
}
memo[n] = f;
return f;
}
Upvotes: 2
Reputation: 2638
Oddly enough, this question has 0 upvotes, but 4 answers, and I don't find any of them really satisfying. Here is an example of implementation + test using 4 different methods and comparing them:
import java.util.ArrayList;
import java.util.HashMap;
public class Fib {
// Straightforward implementation:
public static int fib(int n) {
if (n <= 1) {
return n;
}
return fib(n - 1) + fib(n - 2);
}
// Using array:
static int[] memoArray;
public static int fibArray(int n) {
memoArray = new int[n];
return fibArrayHelper(n);
}
private static int fibArrayHelper(int n) {
if (n <= 1) {
return n;
} else {
if (memoArray[n - 2] != 0) {
return memoArray[n - 2];
}
memoArray[n - 2] = fibArrayHelper(n - 2) + fibArrayHelper(n - 1);
return memoArray[n - 2];
}
}
// Using ArrayList:
static ArrayList < Integer > memoArrayList = new ArrayList < Integer > ();
public static int fibArrayList(int n) {
return fibArrayListHelper(n);
}
private static int fibArrayListHelper(int n) {
if (n <= 1) {
return n;
} else {
if (n - 2 < memoArrayList.size())
return memoArrayList.get(n - 2);
else {
memoArrayList.add(fibArrayListHelper(n - 2) + fibArrayListHelper(n - 1));
return memoArrayList.get(n - 2);
}
}
}
// Using HashMap:
static HashMap < Integer, Integer > memoHash = new HashMap < Integer, Integer > ();
static public int fibHashMap(int n) {
if (n <= 1)
return n;
if (memoHash.get(n) == null) {
memoHash.put(n - 2, fibHashMap(n - 1) + fibHashMap(n - 2));
}
return memoHash.get(n - 2);
}
public static void main(String args[]) {
long preTime, postTime;
int x = 35;
preTime = System.nanoTime();
System.out.printf("%17s: %d", "fib(" + x + ")", fib(x));
postTime = System.nanoTime();
System.out.printf(", computed in %10d nanoseconds.\n", postTime - preTime);
preTime = System.nanoTime();
System.out.printf("%17s: %d", "fibArray(" + x + ")", fibArray(x));
postTime = System.nanoTime();
System.out.printf(", computed in %10d nanoseconds.\n", postTime - preTime);
preTime = System.nanoTime();
System.out.printf("%17s: %d", "fibArrayList(" + x + ")", fibArrayList(x));
postTime = System.nanoTime();
System.out.printf(", computed in %10d nanoseconds.\n", postTime - preTime);
preTime = System.nanoTime();
System.out.printf("%17s: %d", "fibHashMap(" + x + ")", fibHashMap(x));
postTime = System.nanoTime();
System.out.printf(", computed in %10d nanoseconds.\n", postTime - preTime);
}
}
Upvotes: 0
Reputation: 119
I like to use HashMap for Java. From my experience, HashMap makes Memoization really easy to implement. https://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
Four Steps:
Get the base case
Using m.get(n) == null
to check whether or not a sub-problem has been computed.
If (2) is not true, compute it recursively and store it to the HashMap.
The key of the HashMap is the current sub-problems identifier (in the case of Fibonacci, it is the n of the nth Fibonacci sequence. The value is the recursive call that solves the unsolved problem.
If (2) is true, return m.get(n).
Here is an Fibonacci example using the 4 steps:
HashMap<Integer, Integer> memo = new HashMap<Integer,Integer>();
int fib(int n) {
//1. base case
if (n <= 1)
return n;
//2. check if sub problem is computed yet.
if (m.get(n) == null) {
//3. if not, compute the sub problem.
m.put(n, fib(n - 1) + fib(n - 2));
}
//4. if so, return the result.
return m.get(n);
}
You can the same exact approach for a lot of memoization problems.
Upvotes: 0
Reputation: 53819
You can initialize your memo
array with -1
values since the algorithm will never insert-1
in the array.
So checking if memo[i]
has already been inserted means you have to check if memo[i] != -1
.
NB: the concept is actually called memoization
Upvotes: 1
Reputation: 159
You can't compare an array to a single element.
What you probably want is, supposing you have a -1 dummy value for uncomputed values:
if (memo[n] != -1) return memo[n]
Upvotes: 0