剑指 Offer 10- I. 斐波那契数列

思路

递归写法

由题目中给出的斐波那契的递推公式f(n) = f(n - 1) + f(n - 2)可以我们可以直接使用递归来计算每一个f(n)的值,最后回溯的时候使得f(n) = f(n - 2) + f(n - 1)

class Solution {
    final int mod = 1000000007;
    public int fib(int n) {
        if(n <= 1) return n;
        return (fib(n - 1) % mod + fib(n - 2) % mod) % mod;
    }
}

上述的代码应该是最容易想到的代码,但是再上述的代码中进行了大量的重复性的计算,例如f(10)要计算f(9)和f(8),而f(9)又要重复的计算f(8)了,这样就会造成大量的重复计算,使得我们的程序变得极其的慢。

解决方案:使用记忆化的递归

使用一个数组记录我们已经计算哪一项并将结果存在数组中,如果下一次再次碰到这个项的时候,直接返回即可,不需要重复的递归求解

class Solution {
    final int mod = 1000000007;
    int[] st = new int[101];
    {
        st[0] = 0; st[1] = 1;
    }
    public int fib(int n) {
        if(n <= 1) return n;
        if(st[n] != 0) return st[n];
        //回溯之后做加法,表示这个值已经计算完成了
        return st[n] = (fib(n - 1) % mod + fib(n - 2) % mod) % mod;
    }
}

迭代

直接按照斐波那契的公式推过去就行了

class Solution {
    final int mod = 1000000007;
    public int fib(int n) {
        if(n <= 1) return n;
        int a = 0, b = 1, sum = 0;
        for(int i = 0; i < n - 1; ++ i){
            sum = (a % mod + b % mod) % mod;
            a = b; b = sum;
        }

        return sum;
    }
}

也是可以开一个数组dp,使得dp[n] = dp[n - 1] + dp[n - 2],最后直接返回dp[n]就可以了。

如有错误,欢迎指正!
原文地址:https://www.cnblogs.com/Lngstart/p/14713587.html