题目
-
难度:简单
描述
写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 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
提示:
0 <= n <= 100
方法 1
思路
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1
利用递归的方法, 把 问题的计算拆分成 和 两个子问题的计算,并递归,以 和 为终止条件,虽然能求出结果,但是最终会超时;
实现
class Solution {
public int fib(int n) {
if (n == 0 || n == 1) {
return n;
}
return (fib(n - 1) + fib(n - 2)) % 1000000007;
}
}
方法 2
思路
3.2.1 思路
减少暴力递归中的重复运算,可以将子问题的答案存放到备忘录,进行下次运算时先从备忘录中查询,如果已经有对应答案,直接取出用就行,这样就可以大大减少运算的时间。
通过添加备忘录,将原来的递归树进行了剪枝,大大减少了子问题,此时的子问题个数变成了 ,此时的时间复杂度变成了 ;
实现
class Solution {
// 用一个哈希表来当备忘录
HashMap<Integer, Integer> hashMap = new HashMap<>();
public int fib(int n) {
// Base Case
if (n == 0 || n == 1) {
return n;
}
// 如果计算过了,就直接返回对应答案
if (hashMap.containsKey(n)) {
return hashMap.get(n);
} else {
// 没计算过的进行计算,同时存入备忘录
int val =( fib(n - 2) + fib(n - 1)) % 1000000007;
hashMap.put(n, val);
return val;
}
}
}
方法 3
思路
F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1
利用上述条件,利用动态规划的思想;
- 状态定义: 设 为一维数组,其中 的值代表 斐波那契数列第 个数字 。
- 转移方程: ,即对应数列定义 ;
- 初始状态: , ,即初始化前两个数字;
- 返回值: ,即斐波那契数列的第 个数字
- 时间复杂度:此时主要进行循环操作,时间复杂度为 ;
实现
public int fib(int n) {
if(N == 0 || N == 1){
return N;
}
int prev = 0;
int curr = 1;
for(int i = 2; i <= N; i++){
int sum = (prev + curr) % 1000000007;
prev = curr;
curr = sum;
}
return curr;
}
本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情