递归与动态规划--青蛙跳台阶

本题重点不是怎么做出来,而是学习如何优化自己的算法。

问题一:

一只⻘青蛙⼀一次可以跳上1级台阶,也可以跳上2级。求该⻘青蛙跳上⼀一个n级的台阶总共有多少种跳法?

动态规划解题的三个步骤:

  1. 定义dp数组的含义,其中dp数组90%是二维数组,这里问题比较简单,是一维。
  2. 找出数组元素之间的关系式,即dp[n]是可以用dp[n-1],dp[n-2]…dp[1],来推出dp[n]的
  3. 找出初始值

而对于这个问题。dp[i]的含义为:跳上第I级的台阶共有dp[i]种跳法,这样dp[n]就是所要求的。

接下来是找递推关系,青蛙到达第n及台阶有两种方式,一种是从第n-1级跳上来,一种是第n-2级跳上来,所以dp[n]=dp[n-1]+dp[n-2]

寻找初始条件,dp[0]=0,dp[1]=1;这里有一个要注意的地方是当n=2时,dp[2]=2;但若按照公式计算,dp[2]=dp[1]+dp[0]=1,显然不符合,故dp[2]=2也是初始条件。

方案一:
接下来就可以写代码了

int f(int n)
{
if(n<=1)
return n;
int dp[]=new int [n+1];
dp[0]=0;
dp[1]=1;
dp[2]=2;
for(int i=3;i<=n;i++)
{
dp[i]=dp[i-1]+dp[i-2];
}
return dp[n];
}

这种做法时间复杂度是指数级别的,原因是有很多值是重复执行的,所以可以进行优化。
方案二:用Map保存已经计算过的状态

//⽤用⼀一个HashMap来保存已经计算过的状态
static Map<Integer,Integer> map = new HashMap();
public static int solve(int n){
if(n <= 2){
return n;
}else{//是否计算过
if(map.containsKey(n)){
return map.get(n);
}else{
int m = solve(n-1) + solve(n-2);
map.put(n, m);
return m;
}
}
}

方案三:我们还可以不用HashMap来保存状态

public static int solve(int n){
if(n <= 2){
return n;
}
int f1 = 0;
int f2 = 1;
int sum = 0;
for(int i = 1; i<= n; i++){
sum = f1 + f2;
f1 = f2;
f2 = sum;
}
return sum;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值