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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof

题目描述:

写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下:
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:

输入:n = 2
输出:1

示例 2:

输入:n = 5
输出:5

题目分析:
  • f(0) = 0, f(1) = 1, f(n) = f(n - 1) + f(n - 2);
  • n > 1
思路一:

直接将上面的公式转换即可(超时)

代码实现:
class Solution {
    public int mod = 1000000007;
    public int fib(int n) {
        return dfs(n);
    }
    public int dfs(int n) {
        if (n == 0) return 0;
        if (n == 1) return 1;
        int num = (dfs(n - 1) + dfs(n - 2)) % mod;
        return num;
    }
}
思路二:

按照题目中的公式,f(5) = f(4) + f(3),f(4) = f(3) + f(2),f(3) = f(2) + f(1), 可以看出来,很多元素会被重复计算,例如f(5)里面f(3)会计算一次,f(4)里面f(3)又会计算一次,可以使用一个数组将已经计算的f(n)保存起来,避免重复计算。

代码实现:
class Solution {
    public int[] arr;
    public int mod = 1000000007;
    public int fib(int n) {
        arr = new int[n + 1];
        return dfs(n);
    }
    public int dfs(int n) {
        if (n == 0) return 0;
        if (n == 1) return 1;
        if (arr[n] != 0) { // 已经计算过,直接返回
            return arr[n];
        }
        int num = (dfs(n - 1) + dfs(n - 2)) % mod;
        arr[n] = num; 
        return num;
    }
}
思路三:

因为f(n) = f(n - 1) + f(n - 2),直接就可以写出状态转换方程

代码实现:
class Solution {
    public int mod = 1000000007;
    public int fib(int n) {
        int[] dp = new int[n + 1];
        if (n == 0) return 0;
        if (n == 1) return 1;
        dp[0] = 0;
        dp[1] = 1;
        for (int i = 2; i <= n; i++) {
            dp[i] = (dp[i - 1] + dp[i - 2]) % mod;
        }
        return dp[n];
    }
}
思路四:

观察思路三,可以发现,dp[n]的值只与dp[n - 1],dp[n - 2]相关,因此没必要使用数组,只需要保存上一个以及上上一个点值就可以了。

代码实现:
class Solution {
    public int mod = 1000000007;
    public int fib(int n) {
        if (n == 0) return 0;
        if (n == 1) return 1;
        int next = 1; // 上一个值
        int next_next = 0; // 上上一个值
        int result = 0;
        for (int i = 2; i <= n; i++) {
            result = (next + next_next) % mod; // f(n) = f(n - 1) + f(n - 2);
            next_next = next;
            next = result;
        }
        return result;
    }
}

你可能感兴趣的:(剑指 Offer 10- I. 斐波那契数列)