剑指offer面试题牛客_递归和循环_变态跳台阶(java版)

welcome to my blog

剑指offer面试题牛客_递归和循环_变态跳台阶(java版):

题目描述

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

思路

  • 见注释
第三次做; 递推公式最低到f(1), 因为f(0)没有意义
public class Solution {
    public int JumpFloorII(int target) {
        return 1<<target-1;
    }
}
第二次做 注意公式推到过程 f(0)没有含义! 指数与移位 最优解
/*
f(n) = f(n-1) + f(n-2) +...+f(1) + f(0)
f(n+1) = f(n) + f(n-1) + ... + f(1) + f(0)

f(n+1) - f(n) = f(n)

f(n+1) = 2f(n)

f(n+1) = 2f(n) = 4f(n-1) = 8f(n-2) = 2^(n+1)f(0) = 2^(n+1)
这里递推式推错了, 因为f(0)不等于1

f(n+1) = 2^n f(1) = 2^n

f(n) = 2^(n-1); 养成使用移位计算指数的习惯
*/
public class Solution {
    public int JumpFloorII(int target) {
        return 1 << (target - 1);
    }
}
第二次做 循环版
public class Solution {
    public int JumpFloorII(int target) {
        // f(n) = 2f(n-1)
        if(target == 1)
            return 1;
        int a=1, res=0;
        for(int i=2; i<=target; i++){
            res = 2*a;
            a = res;
        }
        return res;
    }
}
使用f(n) = f(n-1)+f(n-2)+…+f(1)+f(0) 递归版 不推荐
public class Solution {
    public int JumpFloorII(int target) {
        /*
        思路:
            1)f(n) = f(n-1) + f(n-2) +...+ f(2) + f(1) + f(0)    这个递归式太长了, 能用是能用, 但是不妨化简一下
        */
        //execute
        if(target == 0) return 1;
        int res=0;
        for(int i=1; i<=target; i++)
            res = res + JumpFloorII(target - i);
        return res;
    }
}
使用f(n) = f(n-1)+f(n-2)+…+f(1)+f(0) 循环版 不推荐, 但要注意使用的是循环嵌套
public class Solution {
    public int JumpFloorII(int target) {
        /*
        思路:
            1)f(n) = f(n-1) + f(n-2) +...+ f(2) + f(1) + f(0)    这个递归式太长了, 能用是能用, 但是不妨化简一下
        */
        //input check
        if(target < 1) return 0;
        //execute
        int[] arr = new int[target+1];
        arr[0] = 1;
        for(int i=1; i<=target; i++)
            for(int j=i-1; j>=0; j--)
                arr[i] += arr[j];
        return arr[target];
    }
}
使用f(n) = 2f(n-1) 递归版
public class Solution {
    public int JumpFloorII(int target) {
        /*
        思路:
            1)f(n) = f(n-1) + f(n-2) +...+ f(2) + f(1) + f(0)
            2)f(n-1) = f(n-2)+...+ f(2) + f(1) + f(0)
            综合1)和2),得到f(n) = 2f(n-1), 这样的递归式就简洁了许多!
        */
        //input check
        if(target<1) return 0;
        //execute
        if(target==1) return 1;
        return 2*JumpFloorII(target-1);
    }
}
使用f(n) = 2f(n-1) 循环版(推荐)
public class Solution {
    public int JumpFloorII(int target) {
        //input check
        if(target<1) return 0;
        //execute
        if(target == 1) return 1;
        int[] arr = new int[target+1];
        arr[1] = 1;
        for(int i=2; i<=target; i++)
            arr[i] = 2*arr[i-1];
        return arr[target];
    }
}
使用f(n) = 2^(n-1); 不要弄错对谁移位! (最优解)
public class Solution {
    public int JumpFloorII(int target) {
        /*
        思路:
            1)f(n) = f(n-1) + f(n-2) +...+ f(2) + f(1) + f(0)
            2)f(n-1) = f(n-2)+...+ f(2) + f(1) + f(0)
            综合1)和2),得到f(n) = 2f(n-1), 这样的递归式就简洁了许多!
            进一步地, f(n) = 2f(n-1)= 2*2f(n-2)=2*2*2f(n-3)= 2^(n-1)*f(1)= 2^(n-1)  学好数学很关键!
        */
        //input check
        if(target<1) return 0;
        //execute
        return 1 << (target-1); //注意是谁移位!!!!! 是1, 不是2!!!!
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值