细谈递归,备忘录递归,动态规划,三种算法思想和运行原理
2018-01-03 22:08
267 查看
大家都知道,数值稍大的递归运行时间对于开发者来说就是场灾难,我们总是想方设法在优化递归,或者说不用递归,此文中从空间时间角度详细剖析以上三种算法的区别,以及运行原理,以斐波那契数为例, 编程语言java 此处为代码
package test1; import java.util.HashMap; public class test2 { private static int count1=0; private static int count2=0; private static int count3=0; public static void main(String[] args) { System.out.println("***********************递归*********************"); long startTime1=System.nanoTime(); System.out.println(getNumber1(30)); long endTime1=System.nanoTime(); System.out.println("方法调用了"+count1+"次数"); System.out.println("时间为:"+(endTime1-startTime1)+"ns"); System.out.println("***********************备忘录递归*********************"); long startTime2=System.nanoTime(); System.out.println(getNumber2(30)); long endTime2=System.nanoTime(); System.out.println("方法调用了"+count2+"次数"); System.out.println("时间为:"+(endTime2-startTime2)+"ns"); System.out.println("***********************动态规划*********************"); long startTime3=System.nanoTime(); System.out.println(getNumber3(30)); long endTime3=System.nanoTime(); System.out.println("方法调用了"+count3+"次数"); System.out.println("时间为:"+(endTime3-startTime3)+"ns"); } //递归 // 832040 // 方法调用了1664079次数 // 时间为:4839154ns public static int getNumber1( int m) { count1++; if(m==1||m==2) { return 1; } else return getNumber1(m-1)+getNumber1(m-2); } // 备忘录算法,自上而下,记住之前算过的值。减少方法的访问次数从而减少运行时间 //方法调用了:57 //832040 //时间为:133048ns private static HashMap<Integer, Integer> hm=new HashMap<>(); public static int getNumber2( int m) { count2++; if(m==1||m==2) { return 1; } else if(hm.containsKey(m)) { return hm.get(m); } else { int value =getNumber2(m-1)+getNumber2(m-2); hm.put(m, value); return value; } } // 动态规划,自下向上的算法 //方法调用了:1 //时间为:3422ns //832040 public static int getNumber3( int m) { count3++; if(m==1||m==2) { return 1; } int a=1; int b=1; int temp=0; for(int x=3;x<=m;x++) { temp=a+b; a=b; b=temp; } return temp; } }
先来说说第一种递归这是一种最常见的递归 也是最好理解的,在这里我就不再赘述,原理和运行方式,只是提一句,这种递归是一种自上向下的递推过程。而它的运行时间,以及调用次数如下。
**这是当参数m为4的时候,由于此方法中只有一个m变量,在内存中运行的时候便不会占用时间和空间,这是比备忘录递归好的地方,当然这也仅仅局限于当参数m小的时候,而随着m的增大直到30,这时候显而易见备忘录递归的优势就会体现出来,这时候在方法调用和运行时间上都有明显的提升,如果说硬要有逊色的话,也就多占了一个hashmap内存空间,不过这在8GB的运行内存中显然不算什么。**
其次,再来说说备忘录递归的运行原理**
这是我在图片编辑器中以参数m=4的时候为例画出的代码流程图,里面详细的介绍了整个备忘录递归算法的运行方向,介绍了hashmap如何存值,何时存值,如果细看的话,相信收获颇丰。 最后再来说说动态规划把,关于它的定义我就不再多费口舌,简单概述,自下而上,把整个数想成一个数组,把a[0]+a[1]的值放在a[2],然后a[1]+a[2]的值放在a[3],以此类推,只要一个循环就可以得出答案了。整个方法因为没有递归的再调用,所以只被调用一次,从而大大减少了运行时间,
相关文章推荐
- 递归和分治思想4|八皇后问题 - 数据结构和算法34
- C/C++中算法运行时间的三种计算方式
- 算法学习 - 树的三种遍历(递归实现)先序遍历,中序遍历,后序遍历
- C/C++中算法运行时间的三种计算方式(By 虚怀若谷)
- 递归是一种算法结构,回溯是一种算法思想
- 【转】C/C++中 算法运行时间的三种计算方式
- C/C++中算法运行时间的三种计算方式
- 算法之递归思想
- JVM三种垃圾收集算法思想及发展过程
- java实现二叉树的三种遍历算法(递归)
- [置顶] Hadoop伪分布安装详解+MapReduce运行原理+基于MapReduce的KNN算法实现
- C/C++中算法运行时间的三种计算方…
- 基础算法思想_递归——斐波那契数列
- 蓝桥杯 ALGO-11算法训练 瓷砖铺放(递归/动态规划)
- JVM三种垃圾收集算法思想及发展过程
- 滚动数组算法 --- DP思想(动态规划)
- 谷歌人工智能算法RankBrain运行原理解析
- 动态规划学习(一)算法思想简介
- 使我对动态规划的理解发生转折的算法的解决过程的思想变化的过程
- 常用算法思想二(动态规划)