个人博客导航页(点击右侧链接即可打开个人博客):大牛带你入门技术栈
动态规划篇
- 从斐波那契数列开始
我们先给出斐波那契数列的常用算法类
public class Fibonacci { private static int num = 0; private Fibonacci() { } public static int fib(int n) { num++; if (n == 0) { return 0; } if (n == 1) { return 1; } return fib(n - 1) + fib(n - 2); } public static void main(String[] args) { num = 0; int n = 20; long start = System.nanoTime(); int res = Fibonacci.fib(n); long end = System.nanoTime(); System.out.println(res); System.out.println((end - start) / 1000000000.0); System.out.println(num); } }
运行结果
6765
3.96599E-4
21891
此时我们调大n的值为40
运行结果
102334155
0.473162902
331160281
再调大n的值为42
267914296
1.302307318
866988873
我们可以看到此处随着n的增大,时间是几何倍数增长,由此我们可知斐波那契数列的时间复杂度为O(2^n)
但我们发现斐波那契数列的存在着大量的重复计算,如下图所示,我们来看计算一个n=5的时候都有哪些重复计算的地方
在这里我们可以看到3被计算了2次。
而2则被计算了3次,这还是n = 5的情况下,如果随着n值的增大,重复计算的次数就会越来越多。
所以我们给出了一个新的记录重复计算值不需要重新计算的斐波那契算法类
public class Fibonacci { private static int num = 0; private static List<Integer> memo = new ArrayList<>(); private Fibonacci() { } //记忆化搜索 public static int fib(int n) { num++; if (n == 0) { return 0; } if (n == 1) { return 1; } if (memo.get(n) == -1) { memo.set(n,fib(n - 1) + fib(n - 2)); } return memo.get(n); } public static void main(String[] args) { num = 0; int n = 42; for (int i = 0;i <= n;i++) { memo.add(-1); } long start = System.nanoTime(); int res = Fibonacci.fib(n); long end = System.nanoTime(); System.out.println(res); System.out.println((end - start) / 1000000000.0); System.out.println(num); } }
这次我们再来计算n = 42,运行结果
267914296
4.2859E-5
83
由结果可知,当我们减少了计算次数,斐波那契算法的时间复杂度从O(2^n)一下子降到了O(n)级别,这就相当于我们在列表中命中了缓存,无需866988873次计算,而计算次数只降低到了83次。
附Java/C/C++/机器学习/算法与数据结构/前端/安卓/Python/程序员必读/书籍书单大全:
(点击右侧 即可打开个人博客内有干货):技术干货小栈
=====>>①【Java大牛带你入门到进阶之路】<<====
=====>>②【算法数据结构+acm大牛带你入门到进阶之路】<<===
=====>>③【数据库大牛带你入门到进阶之路】<<=====
=====>>④【Web前端大牛带你入门到进阶之路】<<====
=====>>⑤【机器学习和python大牛带你入门到进阶之路】<<====
=====>>⑥【架构师大牛带你入门到进阶之路】<<=====
=====>>⑦【C++大牛带你入门到进阶之路】<<====
=====>>⑧【ios大牛带你入门到进阶之路】<<====
=====>>⑨【Web安全大牛带你入门到进阶之路】<<=====
=====>>⑩【Linux和操作系统大牛带你入门到进阶之路】<<=====天下没有不劳而获的果实,望各位年轻的朋友,想学技术的朋友,在决心扎入技术道路的路上披荆斩棘,把书弄懂了,再去敲代码,把原理弄懂了,再去实践,将会带给你的人生,你的工作,你的未来一个美梦。