题目
写一个函数,输入 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。
算法思路
题目简单,动态规划很快的解决。
定义状态:定义数组dp,用于存放斐波那契数列的前n项;
状态转移方程:dp[i] = dp[i-1] + dp[i-2];
初始化:初始化dp[0] = 0, dp[1] = 1;
输出值:求第n项,即为数组dp[n]。
代码
public int fib(int n) {
if(n < 2) return n;
int[] dp = new int[n+1];
dp[0] = 0;
dp[1] = 1;
for(int i = 2;i <= n; i++)
dp[i] = (dp[i-1] + dp[i-2])%1000000007;
return dp[n];
}
其中时间复杂度为O(N),从0~n遍历了一次,空间复杂度为O(N),引入了数组用于存放各项的值。
通过进一步分析,题目要求的只是第N项的值,而前面的不不需要,我们只需要知道第N项的前两项即可,所以可以将上面动态规划优化一下,降低空间复杂度,通过cur记录当前项的值,pre记录N-1项,ppre记录N-2项,每次循环不断更新cur,pre,ppre的值,是空间复杂度降为O(1),时间复杂度O(N)不变。
代码2
public int fib1(int n) {
if(n < 2) return n;
int pre = 1,ppre = 0,cur = 0;
for(int i = 2;i<= n;i++){
cur = (ppre + pre)%1000000007;
ppre = pre;
pre = cur;
}
return cur;
}