JAVA算法动态规划与递归论文_递归与动态规划 - memristor的个人空间 - OSCHINA - 中文开源技术交流社区...

递归:将问题分解成子问题求解,从较小的问题逐渐逼近原始问题,很多时候只需要在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

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

110b5dc9c6b0dab326b9df6bf2c8f3d6.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 

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、编写一个方法确定字符串的所有排列组合

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值