递归与循环-跳台阶

普通跳台阶

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

方法一:循环
/*
对于本题,前提只有 一次 1阶或者2阶的跳法。

a.如果两种跳法,1阶或者2阶,那么假定第一次跳的是一阶,那么剩下的是n-1个台阶,跳法是f(n-1);

b.假定第一次跳的是2阶,那么剩下的是n-2个台阶,跳法是f(n-2)

c.由a\b假设可以得出总跳法为: f(n) = f(n-1) + f(n-2) 

d.然后通过实际的情况可以得出:只有一阶的时候 f(1) = 1 ,只有两阶的时候可以有 f(2) = 2

e.可以发现最终得出的是一个斐波那契数列:

*/

class Solution {
public:
    int jumpFloor(int number) {
        if(number<=2)
            return number;
        if (number >2){
            int a =1,b = 2,result;
            for (int i=3;i<=number;++i){    //将递归变为循环,此时时间复杂度为o(n)
                result = a + b;
                a = b;
                b = result; 
            }
            return result;
        }               
    }
};
方法二:动态规划
class Solution {
public:
    int jumpFloor(int number) {
        if(number <= 0) return -1;
        //if(number==1) return 1;
        //if(number==2) return 2;
        int* dp = new int[number + 1];  //动态规划记录每步的结果,数组下标都是0开始的,故此处+1
        dp[1] = 1;
        dp[2] = 2;
        if(number > 2)
            for(int i = 3; i <= number; ++i)
                 dp[i] = dp[i - 1] + dp[i - 2];

        return dp[number];
        delete[] dp;
    }
};

/*
class Solution {
public:
    int numWays(int n) {
        if (n < 2) { // n=0时返回1
            return 1;
        }
        vector<int> dp(n+1, 0);
        dp[0] = 1;
        dp[1] = 1;
        for (int i = 2; i <= n; i++) {
            dp[i] = (dp[i - 1] + dp[i - 2]) % 1000000007 ; 
        }
        return dp[n];
    }
};
*/

变态跳台阶

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

数学建模:

跳上1级台阶有1种跳法(1)
跳上2级台阶有2种跳法(1-1、2)
跳上3级台阶有4种跳法(1-1-1、1-2、2-1、3)
设跳上n级台阶有f(n)种跳法
f(n)种方法包括:

  1. 跳上1级台阶后直接跳上n级台阶
  2. 跳上2级台阶后直接跳上n级台阶
  3. 跳上3级台阶后直接跳上n级台阶
  4. ……
    n-1. 跳上n-1级台阶后直接跳上n级台阶
    n. 直接跳上n级台阶
    数学归纳法:
    (1)当n=1时,f(n) = 1
    (2)假设当n=k>1时,f(n)=2 ^ (k-1)
    (3)因为 f(n) = f(1) + f(2) + … + f(n-1) + 1
    所以,当n=k+1时, f(n) = f(1) + f(2) + … + f(k) + 1 = 2 ^ k
    综上
    f(n) = 2 ^ (n-1)

代码实现:

public static int JumpFloorII(int target) {
    if(target <= 0) 
        return 0;
    int result = 1;
    for(int i = 0; i < target-1; ++i) {
        result *= 2;
    }
    return result;
}
class Solution{
public:
     int jumpFloorII(int number){
         if (number <=0)
             return -1;
         if (number >0){
             int results = pow(2,number -1);    
             //int results = 2^(number-1);     此表述为错误的,c++乘方不能这么表示
             return results;
         }
     } 
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值