0
点赞
收藏
分享

微信扫一扫

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

菜头粿子园 2021-09-21 阅读 45
题目描述:
示例 1:
示例 2:
题目分析:
  • 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;
    }
}
举报

相关推荐

0 条评论