青蛙跳台阶

一只青蛙一次可以跳上一级台阶,也可以跳上二级台阶,求该青蛙跳上一个n级的台阶总共需要多少种跳法。

当n等于1的时候,只需要跳一次即可,只有一种跳法,记f(1)=1;

当n等于2的时候,可以先跳一级再跳一级,或者直接跳二级,共有2种跳法,记f(2)=2;

当n等于3的时候,他可以从一级台阶上跳两步上来,也可以从二级台阶上跳一步上来,所以总共有f(3)=f(2)+f(1);

当n等于n的时候,总共有f(n)=f(n-1)+f(n-2)(这里n>2)种跳法。

public static int f(int n){
    if(n<=0){
        return 0;
    }
    if(n==1){
        return 1;
    }
    if(n==2){
        return 2;
    }
    return f(n-1)+f(n-2);
}

计算f(6):

递归会重复计算已经计算过的值,效率明显不是很高,所以可以把计算过的值储存起来,防止重复计算。

public class JumpFrog {
    public static int f2(int n, HashMap<Integer,Integer> map){
        if(n<=0){
            return 0;
        }
        if(n==1){
            return 1;
        }
        if(n==2){
            return 2;
        }

        if(map.containsKey(n)){
            return map.get(n);
        }
        int first=f2(n-1,map);
        int second=f2(n-2,map);
        int sum=first+second;
        map.put(n,sum);
        return sum;
    }
    
    // 非递归方法
    public static int f3(int n){
        if(n<=0){
            return 0;
        }
        if(n==1){
            return 1;
        }
        if(n==2){
            return 2;
        }

        int first=1,second=2,sum=0;
        while(n-- > 2){
            sum=first+second;
            first=second;
            second=sum;
        }
        return sum;
    }
}

变态跳台阶:一只青蛙一次可以跳上一级台阶,也可以跳上二级台阶……,也可以跳n级,求该青蛙跳上一个n级的台阶总共需要多少种跳法。

递推格式:

f(n)=f(n-1)+f(n-2)+……+f(2)+f(1);

f(n-1)=f(n-2)+f(n-3)+……+f(2)+f(1);

所以得出:f(n)=f(n-1)+f(n-1)=2*f(n-1),且f(1)=1。

private static int f4(int n){
    if(n==1){
        return 1;
    }
    return f4(n-1)*2;
}
private static int f5(int n){
    if(n==1){
        return 1;
    }
    return 1<<(n-1);
}

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

分开讨论:

1,如果 n<=m;因为只能往上跳不能往下跳,所以大于n的都不可以跳,如果跳了就直接超过了,只能跳小于等于n的数字,那么这个问题就直接退到问题2了。

2,如果 n>m;我们要想跳到n级台阶,我们可以从n-1级跳一步上来,或者从n-2级跳两步上来,或者从n-m级跳m步上来,

所以得到地推公式: f(n) =  f(n-1) + f(n-2) + f(n-3) + ... + f(n-m);

进一步可以推出:f(n-1) =   f(n-2) + f(n-3) + ... + f(n-m) + f(n-m-1);

化简结果为:f(n) = 2f(n-1) - f(n-m-1);(n>m)

public static int f6(int n,int m){
    if(n<=1){
        return 1;
    }
    // 总台阶大于跳的最高级台阶
    if(n>m){
        return 2*f6(n-1,m)-f6(n-1-m,m);
    }
    return 2*f6(n-1,n);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值