面试之路(25)-斐波那契数列类问题的详解

斐波那契数列介绍:

这里写图片描述

常见的递归解法:

int Fibonacci(int n){
    if(n <= 0){
        return 0;
    }
    if(n == 1){
        return 1;
    }
    return Fibonacci(n-1)+Fibonacci(n-2);
}

递归解法的效率分析:

面试之路(25)-斐波那契数列类问题的详解_第1张图片
这棵树是调用树,有好多节点是重复的。随着n的增大,重复的节点数目急剧增大。时间复杂度随着n是指数增加的。

循环的效率更高的改进方法:

int Fibonacci(int n){
    if(n <= 0){
        return 0;
    }
    if(n == 1){
        return 1;
    }
    int prev = 1;
    int next = 0;
    int all = 0;
    for(int i = 2;i <= n;++i){
        all = prev + next;
        next = prev;
        prev = all;
    }
    return all;
}

上述解法的时间复杂度为o(n)

时间复杂度为o(lgn)的解法:

数学先验知识:

这里写图片描述
上面的公式可以用数学归纳发求得,转化为求矩阵的乘积。
时间复杂度仍然为o(n)。

乘方的优化算法,降低到O(lgn)

这里写图片描述

斐波那契的变形问题:

变形一(青蛙跳面试题,leetcode上面有):

一只青蛙一次跳一级或者2级台阶,求青蛙条n级台阶的方法数目?

思路:

s(n) = s(n-1)+s(n-2),本质是斐波那契数列问题

进一步扩展:

青蛙,一次可以条1,2到n级台阶,那么跳上n级台阶,方法数目?

思路:

f(n) = 2^(n-1);
可以用数学归纳法证明

斐波那契变形二:(方块面试题)

把一个2*1的方块,放进82*1的方块,一共有多少种方法?

这里写图片描述

思路分析:

最后一块竖着放,还需要f(7),横着放的话,是f(6),
f(8) = f(7)+f(6);

总结:

斐波那契问题灵活应用是解题关键

你可能感兴趣的:(算法,面试,递归,非递归,斐波那契)