美文网首页
面试题10:斐波那锲数列及其应用

面试题10:斐波那锲数列及其应用

作者: 繁星追逐 | 来源:发表于2019-08-15 09:01 被阅读0次

现在要求输入一个整数n,请你输出斐波那契数列的第n项。
很明显递归解决:
从上往下递归,低效重复计算多
所以选择从下往上进行递归

public class Fibonacci {

    /**
     * 低效递归法
     */
    public int Fibonacci1(int n) {
        if (n==0){
            return 0;
        }
        if (n==1){
            return 1;
        }
        return Fibonacci1(n-1) + Fibonacci1(n-2);
    }

    /**
     * 从下往上递归,相对高效,时间复杂度为o(n)
     */
    public int Fibonacci(int n) {
       int[] result = {0,1};
       if (n<2){
           return result[n];
       }
       int fn1 = 0,fn2 = 1,current = 0;
       for (int i=2;i<=n;i++){
           current = fn1+fn2;
           fn1 = fn2;
           fn2 = current;
       }
       return current;
    }

题型二:
一只青蛙一次可以跳上1级台阶,也可以跳上2级。
* 求该青蛙跳上一个n级的台阶总共有多少种跳法。
分析:我们可以认为n级台阶,最后一跳可以选择跳一阶或者跳两阶,
* 如果跳一阶,则相当于前面n-1级台阶的跳法,跳两阶,则相当于前面n-2阶台阶的跳法
* 因此第n阶相当于n-1的跳法加上n-2的跳法
* 由于一个台阶只有一种跳法,两个台阶有两种跳法
* 类推下去

代码如下:

public int JumpFloor(int target) {
       if (target <=0){return 0;}
       if (target ==1){return 1;}
       if (target ==2){return 2;}
       int fn1=1,fn2=2,current=0;
       for (int i=3;i<=target;i++){
           current = fn1 + fn2;
           fn1 = fn2;
           fn2 = current;

       }
       return current;
    }

题型3:上述题目改成青蛙可以一次跳一到n级台阶,问有多少种可能?
f(0)= 0
f(1)= 1
f(2)= f(1)+f(0)= f(2-1) + f(2-2)
f(3)= f(3-1) + f(3-2) + f(3-3)
......
f(n-1)= f(0) + f(1)+f(2)+f(3) + ... + f((n-1)-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)

因此可以推出:f(n)= 2*f(n-1);

public int JumpFloorII(int target) {
        if (target <=0){return 0;}
        if (target == 1){return 1;}
        int fn = 0,fn1=1;
        for (int i=2;i<=target;i++){
            fn = 2*fn1;
            fn1 = fn;
        }
        return fn;
    }

    /**
     * fn=2^n-1
     * @param target
     * @return
     */

    public int JumpFloorII0(int target) {
        if (target <=0){return 0;}
        return (int)Math.pow(2,target-1);
    }

    /**
     * 由上到下的递归
     * @param target
     * @return
     */
    public int JumpFloorII1(int target) {
        if (target <=0){return 0;}
        if (target == 1){return 1;}
        return 2*JumpFloorII1(target-1);
    }

题型三:
我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。
请问用n个2
1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
思路:例如我们把当前覆盖方法计为f(n),小矩形有两种覆盖方式,第一种竖着覆盖,则为后面n-1个覆盖的方法,第二种横着覆盖,则下面也需要一个矩形,后面还剩n-2个矩形;所以可得f(n)= f(n-1)+f(n-2) n>2;
f(1) = 1;f(2)= 2;

/**
     * 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。
     * 请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?
     * @param target
     * @return
     */
    public int RectCover(int target) {
       if (target <= 0){return 0;}
       if (target == 1){return 1;}
       if (target == 2){return 2;}
       int current=0,fn1=1,fn2=2;
       for (int i=3;i<=target;i++){
           current = fn1 + fn2;
           fn1 = fn2;
           fn2 = current;
       }
       return current;
    }

    /**
     * 通过减法获得原来的改变后的和,少用一个变量
     * @param target
     * @return
     */
    public int RectCover0(int target) {
        if (target <= 0) {
            return 0;
        }
        if (target == 1) {
            return 1;
        }

        int a = 1;
        int b = 2;
        while (target > 1) {
            b = a + b;
            a = b - a;
            target--;
        }
        return a;
    }

相关文章

网友评论

      本文标题:面试题10:斐波那锲数列及其应用

      本文链接:https://www.haomeiwen.com/subject/ikrijctx.html