题目:
写一个函数,输入 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。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解:
解法一:
class Solution {
public int fib(int n) {
/**动态规划典型例题
注意:答案取模 1e9+7 */
if(n<=1) return n; //递归出口:n<=1时,fib(n)=n
int[] dp = new int[n+1]; //状态定义:dp[i]为斐波那契第i项
int i = 2;
dp[0] = 0; dp[1] = 1;
while(i<=n){
dp[i] = (dp[i-1] + dp[i-2]) % 1000000007; //转移方程:dp[i+1] = dp[i] + dp[i-1]
i++;
}
return dp[n]; //返回值:dp[n]
}
}
笔记:
(1)学习动态规划时最经典的例题,使用递归深度过高容易溢出,而动态规划可以解决这个问题
(2)错误点:
错误 | 改正 | 备注 |
int[] dp = new int[]; | int[] dp = new int[n+1]; | 和js不同,应当在初始化时就确定数组一维大小 |
dp[0] = 0; dp[1] = 1 | dp[0] = 0; dp[1] = 1; | 忘记在后面加分号(代码习惯问题) |
(3)改进方向:因为每次都是两数相加,所以可以将dp数组改为sum,a,b,节省空间(?)
解法二:
class Solution {
public int fib(int n) {
/**动态规划典型例题
注意:答案取模 1e9+7 */
if(n <= 1) return n;
int sum = 0, a = 0, b = 1; //a:第n位斐波那契数;b:第n+1位斐波那契数
for(int i = 0; i < n; i++){
sum = (a + b) % 1000000007;
a = b;
b = sum;
}
return a;
}
}
笔记:
(1)使用三个变量代替数组,本以为会节省空间,但实际效果emmm
(2)注意a,b分别对应哪位斐波那契数,i的起始如果是1,返回的则应该是b