博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
递归与动态规划
阅读量:6954 次
发布时间:2019-06-27

本文共 2176 字,大约阅读时间需要 7 分钟。

hot3.png

递归:将问题分解成子问题求解,从较小的问题逐渐逼近原始问题,很多时候只需要在f(n-1)中加入或移除某些东西或稍作修改就可以求得f(n)

动态规划与递归的区别:动态规划要将中间的结果缓存起来以备后续使用

1、斐波那契数列问题

public class fibonacci {	private final static int max=1000;		/**	 * 递归方法,时间复杂度2^i	 * @param i	 * @return	 */	public static long recursion(int i) {		if (i == 0)			return 0;		if (i == 1)			return 1;		return recursion(i - 1) + recursion(i - 2);	}			private static long[] temp=new long[max];	/**	 * 动态规划方法,将中间结果缓存起来,时间复杂度 i	 * @param i	 * @return	 */	public static long dynamic(int i){		if (i == 0)			return 0;		if (i == 1)			return 1;		if(temp[i]!=0){			return temp[i];		}		temp[i]=dynamic(i-1)+dynamic(i-2);		return temp[i];	}	public static void main(String[]args) {		long startTime = System.currentTimeMillis(); // 获取开始时间		System.out.println(recursion(40));		long endTime = System.currentTimeMillis(); // 获取结束时间		System.out.println("程序运行时间: " + (endTime - startTime) + "ms");				long startTime2 = System.currentTimeMillis(); // 获取开始时间		System.out.println(dynamic(40));		long endTime2 = System.currentTimeMillis(); // 获取结束时间		System.out.println("程序运行时间: " + (endTime2 - startTime2) + "ms");	}}

运行结果

102334155

程序运行时间: 1145ms

102334155

程序运行时间: 0ms

递归算法的空间效率很低,每次递归调用都会在栈上增加一层

153224_2gnH_81653.gif

参考:

扩展:

用8个1*2的小长条去覆盖一个2*8的棋盘,要求完全覆盖棋盘,小长条彼此不重叠。求总共有多少总覆盖方法。

其实就是fibonacci数列

分析见 

2、楼梯问题

楼梯有n阶台阶,一次可以上1阶,2阶,或3阶,计算有多少种上楼梯的方式

小孩上完楼梯最后一步即抵达第n阶的那一步,可能走1阶或2阶或3阶,最后一步可能是第n-1阶向上走1,或n-2向上走2,或n-3向上走3,同样用递归问题可以解决

public class stair {		public static int getMethods(int num) {		if (num<0) {			return 0;		}		if (num==0) {			return 1;		}		return getMethods(num-1)+getMethods(num-2)+getMethods(num-3);	}	public static void main(String[] args) {		System.out.println(getMethods(6));	}}

输出结果为:

24

扩展:

用1分、2分和5分的硬币凑成1元,共有多少种不同的凑法?(华为机试题)

参考:

这个不能用上述方法,因为走楼梯不同顺序是不同的走法,而硬币的凑法则与顺序无关,写程序可用穷举法

public class coin {		public static int getKinds(){		int num=0;		for (int i = 0; i < 21; i++) {			for (int j = 0; j <= 100-5*i; j++) {				for (int k = 0; k <= 100-5*i-2*j; k++) {					if(5*i+2*j+k==100){						num++;					}				}			}		}		return num;	}	public static void main(String[] args) {		System.out.println(getKinds());	}}

输出:

541

3、编写一个方法返回集合的所有子集

4、编写一个方法确定字符串的所有排列组合

转载于:https://my.oschina.net/hnuweiwei/blog/223445

你可能感兴趣的文章
在阿里云服务器windows server2012r iis上部署.net网站
查看>>
为easyui添加多条件验证
查看>>
Linux mem/swap/buffers/cached 区别
查看>>
13 memcache服务检查
查看>>
go install之后没有生成bin目录的原因(环境变量GOBIN)
查看>>
uva 10441(poj 2337 欧拉通路)
查看>>
DS博客作业07--查找
查看>>
Codeforces_733C
查看>>
[改善Java代码]动态加载不适合数组
查看>>
Mysql打开日志信息
查看>>
javaScript----Http对象封装
查看>>
Struts2入门
查看>>
纯JS,AJAX
查看>>
数据结构上机1顺序表
查看>>
如何搭建自己的SPRING INITIALIZR server
查看>>
JDK5-注解
查看>>
定义表单控件的id和name注意点
查看>>
UILabel里字体带下划线
查看>>
Ios开发之多线程编程——NSThread
查看>>
linux下网站压力测试工具webbench
查看>>