剑指offer打卡Day10:变态跳台阶

题1:变态跳台阶

题目描述

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

示例

输入

3

返回值

4

解析:

  • 规律分析:

    台阶        :      跳法
    0                   0
    1                   1
    2                   2  (1,2)
    3                   4  (111,12,21,3)
    4                   8  (1111,211,112,121,22,31,13,4)
    ...以此类推
    
  • 根据上一题思路逆向推导:

    • 假设青蛙已经跳到了第n级台阶,那么它有可能最后一步是在:

    • 第n-1级台阶

      • 此时有f(n-1)种跳法
    • 第n-2级台阶

      • 此时有f(n-2)种跳法

        …以此类推

    • 第n-n级台阶

      • 此时有f(n-n)种跳法,f(0) = 1,一步登天
    • ~

    • 上述台阶跳上第n级台阶

  • 公式推导:

    • 根据上述思路,用f(n)来表示跳n级台阶的跳法数量:

      f(1)=1表示跳1级台阶的跳法数量;
      f(2)=2表示跳2级台阶的跳法数量;
      f(3)=f(2)+f(1)+1 
      	可以递推出   f(n)=f(n-1)+f(n-2)+ ... +f(1)+1 ;
               同理 f(n-1)=f(n-2)+f(n-3)+ ... +f(1)+1 ;
      将两式相减可以求出递推公式:
      	f(n)-f(n-1)=f(n-1),
      	即f(n)=2*f(n-1) 
      
    • 此时可以得出:

                |—— 1, (n=0)
                |
          f(n) =|—— 1, (n=1)
                |
                |—— 2*f(n-1) (n>=2,n为整数)
      
  • 逻辑带师:

    ​ 转自牛客:

    每个台阶都有跳与不跳两种情况(除了最后一个台阶),最后一个台阶必须跳。所以共用2^(n-1)中情况

  • 实现方式:

    • 既然已经求出通项公式,自然可以用递归方法解决。

    • 但是经常用递归消耗大,可以用数组优化

      用数组优化此类递归的方式为动态规划思想

解答:

//经典递归方法
public int JumpFloorII(int target) {
    if (target <= 0) {
        return -1;
    } else if (target == 1) {
        return 1;
    } else {
        return 2 * JumpFloorII(target - 1);
    }
}

//动态规划优化
public int JumpFloorII_dp(int target) {
    if(target==0){   //如果为0层台阶时,返回0
        return 0;
    }
    int a[] = new int[target+2];   //加2的原因是下面的a数组要初始化到第三个元素
    int b=3; //如果小于3的话直接取值
    a[0]=1;
    a[1]=1;
    a[2]=2;
    if(target<b && target>0){
        return a[target];
    }
    for(int i=3;i<=target;i++){
        a[i]=2*a[i-1];
    }
    return a[target];
}

//数学推导法:
/**
根据f(1)=1和f(n)=2∗f(n−1),我们最终可以得到,f(n)=2^(n−1)。
结论也符合逻辑大师的结论。
*/
public int JumpFloorII_withMath(int target) {
    return 1<<(target-1);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值