青蛙跳台阶的相关问题

   日期:2020-11-04     浏览:90    评论:0    
核心提示:青蛙跳台阶的相关问题问题一:青蛙一次只能跳 1 个台阶或者 2 个台阶, 计算从 0 台阶跳到 n 台阶有多少跳法,也就是的路径种类总和。import java.util.HashMap;public class StepJump { // 当青蛙只能跳 1 个台阶或者 2 个台阶, 计算从 0 台阶跳到 n 台阶的路径种类总和 // 这个类似斐波那契数列 1 1 2 3 5 8 13 // f(0)=1, f(1)=1, f(2)=f(0)+f(1),[其中f(0)表示从0

青蛙跳台阶的相关问题

问题一:青蛙一次只能跳 1 个台阶或者 2 个台阶, 计算从 0 台阶跳到 n 台阶有多少跳法,也就是的路径种类总和。

import java.util.HashMap;

public class StepJump { 
    // 当青蛙只能跳 1 个台阶或者 2 个台阶, 计算从 0 台阶跳到 n 台阶的路径种类总和
    // 这个类似斐波那契数列 1 1 2 3 5 8 13
    // f(0)=1, f(1)=1, f(2)=f(0)+f(1),[其中f(0)表示从0阶直接跳到2阶] f(3)=f(1)+f(2)
    // f(3)=f(1)+f(2)的解释:[先跳到1阶的路径种类(然后直接跳到3阶)+先跳到2阶的路径种类(然后直接跳到3阶)]
    private static int fun1(int n) { 
        if(n < 2)
            return 1;
        // [先跳到n-1阶的路径种类(然后直接跳到n阶)+先跳到n-2阶的路径种类(然后直接跳到n阶)]
        return fun1(n-1)+fun1(n-2); // 递归
    }
    // 避免重复计算,可用一个 HashMap 存储计算过的值,防止重复计算。
    private static int fun2(int n, HashMap<Integer, Integer> map) { 
        if(n < 2)
            return 1;
        // 如果map包含 n 对应的值,直接返回
        if(map.containsKey(n))
            return map.get(n);
        // 递归求值,和fun1()同样道理
        int first = fun2(n-1, map);
        int second = fun2(n-2, map);
        int sum = first + second;
        // 储存值,方便下次寻找
        map.put(n, sum);
        return sum;
    }
    // 利用循环计算,效率更高
    private static int fun3(int n) { 
        if(n < 2)
            return 1;
        int first = 1, second = 1, sum = 0;
        while(n-- >= 2) { 
            sum = first + second;
            first = second;
            second = sum;
        }
        return sum;
    }
    public static void main(String[] args) { 
        int  n = 40;
        long time = System.nanoTime();
        System.out.println(fun1(n));
        System.out.println("递归时间:" + (System.nanoTime() - time));
        time = System.nanoTime();
        System.out.println(fun2(n, new HashMap<Integer, Integer>()));
        System.out.println("HashMap时间:" + (System.nanoTime() - time));
        time = System.nanoTime();
        System.out.println(fun3(n));
        System.out.println("循环时间:" + (System.nanoTime() - time));
    }
}

问题二:青蛙一次能跳 1 到 n 个台阶, 计算从 0 台阶跳到 n 台阶有多少跳法,也就是的路径种类总和。

public class StepJumpTwo { 
    // 青蛙一次能跳 1 到 n 个台阶, 计算从 0 台阶跳到 n 台阶的路径种类总和
    // f(n) = f(n-1)+f(n-2)+......+f(1)+f(0)------a式子
    // f(n-1)= f(n-2)+f(n-3)+......+f(1)+f(0)------b式子
    // (a式子)-(b式子)得 f(n)-f(n-1)=f(n-1)
    // 最终得到 f(n)=2*f(n-1)的等比数列,该等比数列为2^(n-1)
    private static int fun(int n){ 
        if(n < 2)
            return 1;
        return 1<<(n-1);  // 位运算,速度更快
    }
    public static void main(String [] args){ 
        System.out.println(fun(10));
    }
}

问题三:青蛙一次能跳 1 到 m 个台阶, 计算从 0 台阶跳到 n 台阶有多少跳法,也就是的路径种类总和。

public class StepJumpThree { 
    // 青蛙一次能跳 1 到 m 个台阶, 计算从 0 台阶跳到 n 台阶的路径种类总和

    // 情况1 n <= m 时,也就回到了问题二 f(n)=2*f(n-1), 等比数列为2^(n-1)

    // 情况2 当 n-1 = m 时
    // f(n) = f(n-1)+f(n-2)+......+f(2)+f(1) 接下所有的计算又回到情况1
    // = 2*f(n-2)+2*f(n-3)+......+2*f(1)+f(1)
    // = ......
    // = 2^(n-1)-1 (f(n)=2*f(n-1)的等比数列[2^(n-1)]的前 n-1 项和[2^(n-1)-1]

    // 情况3 当 n-1 > m 时
    // f(n) = f(n-1)+f(n-2)+......+f(n-m+1)+f(n-m)------a式子
    // f(n-1)= f(n-2)+f(n-3)+......+f(n-m)+f(n-1-m)------b式子
    // (a式子)-(b式子)得 f(n)-f(n-1)=f(n-1)-f(n-1-m)
    // 最终得到 f(n)=2*f(n-1)-f(n-1-m)

    private static int fun(int n, int m){ 
       if(n < 2)
           return 1;
       if(n <= m)     // 情况1
           return 1<<(n-1);
       if(n-1 == m)   // 情况2
           return (1<<(n-1))-1;
        // 情况3
       return 2*fun(n-1, m)+fun(n-1-m, m);
    }
    public static void main(String [] args){ 
        System.out.println(fun(1, 5));  // n < 2
        System.out.println(fun(4, 5));  // 情况1
        System.out.println(fun(6, 5));  // 情况2
        System.out.println(fun(7, 5));  // 情况3
    }
}

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服