写一个函数,输入 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
思路:
还是先用老办法,用一个数组存放每一项的值😀
代码:
class Solution {
public int fib(int n) {
//1.判断特殊情况
if(n == 0){
return 0;
}
//n是从0开始的。所以数组长度是n+1
int[] arr = new int[n+1];
arr[0] = 0;
arr[1] = 1;
//给数组的每一项赋值
for(int i=2; i<n+1; i++){
arr[i] = (arr[i-1] + arr[i-2])%1000000007;
}
//返回第n项
return arr[n];
}
}
复杂度分析:
时间复杂度:O(n)
空间复杂度:O(n)
改进思路:
参照了leetcode的官方题解。
我们只需要得到第n项。第n项是由前两项相加得到的。我们只需要在数列中从头开始两两向后移动计算,中间的那些数不用专门保存下来。可以节省空间复杂度。
代码
class Solution {
public int fib(int n) {
//1.判断特殊情况
if(n == 0){
return 0;
}
if(n == 1){
return 1;
}
//2.设两个变量不停向前移动
int a = 0;
int b = 1;
//3.不断后移
//这是前两个变量相加在一起的和
int sum = 1;
//n=1时,相加后a向后移动一位,正好是第1个元素
//n=2时,相加后a移动,正好是第2个元素
//n=n时,相加后a移动,正好是第n个元素
for(int i=0; i<n; i++){
sum = (a+b) % 1000000007;
a = b;
b = sum;
}
//4.返回a
return a;
}
}
复杂度分析:
时间复杂度:O(n)。for循环计算sum
空间复杂度:常量大小的额外空间,O(1)