跳阶梯问题及其进阶版

原问题: 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

分析:

思路一:问题可以简化为:n每次可以减1或者减2两种方式直到减到0为止,有多少种减法。可以得到一个二叉树:
在这里插入图片描述
现在问题就转化为数值为0的结点有多少个的问题。
思路一实现代码:

public int JumpFloor(int target) {            //target表示楼梯阶数
    if(target==0){
        return 0;
    }else{
        return JumpCont(target);
    }
}
public int JumpCont(int target){
    if(target==0)
        return 1;
    else{
        return JumpCont(target-1) + (target-2>=0 ? JumpCont(target-2):0);    //注意:如果target-2<0了那就不能进入这个分支
    }
}

思路二:动规
先思考当n=1时,显然只有一种上楼方法;当n=2时,有两种上楼方法;当n=3时,情形如下:
在这里插入图片描述
由图可知,当n=3又可以转化为n=1的情形加上n=2的情形,所以当n=3时,有1+2=3中上楼方法;当n=4时,又可以拆分为n=3和n=2的情形,所以有3+2中上楼方法;……
由这个规律可以得出一个规律是:假设f(target)是返回结果的函数,那么f(target) = f(target-1)+f(target-2);且当target=1时,f(target)=1;当target=2时,f(target)=2;这其实就是斐波那契数列数列,方法一其实就是斐波那契数列的递归求解方法。由公式可以创建一个数组来保存f(target-1)和f(target-2)的计算结果。
思路二代码实现:

public int JumpFloor(int target) {
        if(target == 0)
            return 0;
        else if(target == 1){
            return 1;
        }else if(target == 2){
            return 2;
        }
        int d[] = new int[target+1];
        d[0] = 0;
        d[1] = 1;       //target=1时,只有一种上楼梯的方法
        d[2] = 2;		//target=2时,有两种上楼的方法
        for(int i=3;i<=target;i++){
            d[i] = d[i-1]+d[i-2];
        }
        return d[target];
    }

进阶问题:
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

分析:只考虑动规,公式还是和前面一样,当n=1时,f(n)=1,表示只有一种跳法;当n=2时,f(n)=2,有两种跳法,注意当n=3时,f(3) = f(2) + f(1) + 1,这后面的加1表示加上一次跳3级的这种跳法;这样就可以得到公式:f(n) = f(n-1) + f(n-2) + 1;

代码实现:

public int JumpFloorII(int target) {
    if(target==0)
        return 0;
    else if(target==1)
        return 1;
    else if(target==2)
        return 2;
    int[] dp = new int[target+1];
    dp[0]=0;
    dp[1]=1;
    dp[2]=2;
    int i=3,tmp;
    for(;i<=target;i++){
        tmp=0;
        for(int j=1;j<i;j++){
            tmp += dp[j];
        }
        dp[i] = tmp+1;
    }
    return dp[target];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值