用斐波那契数列来过度,结合油管上一个讲得比较好的tutorial,感受一下
递归-->记忆化搜索-->dp的过程。
以下是斐波那契数列的各个solution的实现。
public class FibDemo {
// https://www.youtube.com/watch?v=1BAsAgdx7Ac
// {1, 1, 2, 3, 5, 8, 13, ...}
/*************************************************
* 普通递归
*************************************************/
private long fib1(int n) {
if (n < 1) return -1;
if (n == 1 || n == 2) return 1;
return fib1(n - 1) + fib1(n - 2);
}
/*************************************************
* 记忆化搜索 (自上而下,人人为我)
*************************************************/
private Map<Integer, Long> memo;
private long fib2(int n) {
memo = new HashMap<>();
return help(n, memo);
}
private long help(int n, Map<Integer, Long> map) {
if (n == 1 || n == 2) return 1; // base case: 1和2直接返回
if (map.containsKey(n)) return map.get(n); // 先查表,表中有则直接返回
long res = help(n - 1, memo) + help(n - 2, memo); // 表中无,计算之
map.put(n, res); // 计算结果放入表中,方便下次查询
return res;
}
/*************************************************
* DP (自下而上,我为人人)
*************************************************/
private long fib3(int n) {
long[] dp = new long[n + 1]; // 用dp记录结果
dp[1] = 1;
dp[2] = 1;
// 依次计算并填表
for (int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n]; // 直接返回
}
public static void main(String[] args) {
FibDemo f = new FibDemo();
int n = 45;
long time = System.currentTimeMillis();
System.out.println("普通递归结果:\t\t" + f.fib1(n) + ", 耗时" + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
System.out.println("记忆化搜索结果:\t" + f.fib2(n) + ", 耗时" + (System.currentTimeMillis() - time));
time = System.currentTimeMillis();
System.out.println("DP结果:\t\t\t" + f.fib3(n) + ", 耗时" + (System.currentTimeMillis() - time));
}
}
普通递归结果: 1134903170, 耗时3255
记忆化搜索结果: 1134903170, 耗时1
DP结果: 1134903170, 耗时0
Process finished with exit code 0
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。