每天一道算法题——变态跳台阶

题目描述
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
测试用例:
0 1 2 3 4 … 10
对应输出应该为:
0 1 2 4 8 … 512

分析:这里有两种分析方法,第二种一定会惊艳到你的。

  1. 根据上述测试用例及结果,差不多已经可以看出来一些规律了。
    但是这里再进行一细节方面的分析:
    f(1) = 1
    f(2) = f(2-1) + f(2-2) //f(2-2) 表示2阶一次跳2阶的次数。
    f(3) = f(3-1) + f(3-2) + f(3-3)

    f(n) = f(n-1) + f(n-2) + f(n-3) + … + f(n-(n-1)) + f(n-n)
    由上述可推导出:
    f(n-1) = f(0) + f(1) + f(2) + f(3) + … + f(n-2)
    f(n) = f(0) + f(1) + f(2) + f(3) + … + f(n-2) + f(n-1) = f(n-1) + f(n-1)
    则可以得出最终结论,在n阶台阶,一次有1、2、…n阶的跳的方式时,总得跳法为:
              | 0 ,(n=0 )
    f(n) = | 1 ,(n=1 )
              | 2*f(n-1),(n>=2)
    以上,可以看出,若台阶大于0的话,青蛙跳的方法共有2(n-1)种。

  2. 但网络上有网友提出了另外一种更加有效地分析:
    每个台阶都有跳与不跳两种情况(除了最后一个台阶),最后一个台阶必须跳。所以共用2^(n-1)中情况
    不得不说,这个思路实在实在是精辟。

源码:

public class Test1 {
    public int JumpFloorII(int target) {
        if (target<1) {
            return 0;
        }else {
            return (int) Math.pow(2, target-1);
        }
    }
}

2^(n-1)也可以用左移操作进行。

public class Test1 {
    public int JumpFloorII(int target) {
    if (target<1) {
            return 0;
        }else {
        return  1<<--target;
        }
    }
}

但是这样代码会比较不容易阅读,而且Java的Pow函数底层也是调用的native方法,速度和内存占用和左移操作是差不了多少的。
Java中的Pow函数
运行测试:

第一种:
运行时间:15ms
占用内存:22600k
第二种:
运行时间:15ms
占用内存:22052k

从测试结果可以看出,确实是差不多的。

总结:
思考问题的时候,不要拘泥于一种思路,从多方面去看待问题,往往会有不一样的风景。正所谓“横看成岭侧成峰”啊。

你可能感兴趣的:(算法练习,Java,每天一道算法题,算法,剑指offer-java实现,递归,惊艳)