剑指 Offer 10- I. 斐波那契数列
题目:斐波那契数列
-
LeetCode地址:剑指 Offer 10- I. 斐波那契数列
-
描述:
写一个函数,输入
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。
-
示例:
输入:n = 2 输出:1 输入:n = 5 输出:5
题解:
求余运算规则: 设正整数 a, b, p ,求余符号为 % ,则:(a + b) % p = (a % p + b % p) % p
方法一:额外数组
-
思路:使用额外数组存储计算过的值
-
代码:
public int fib(int n) { if (n == 0) { return 0; } if (n == 1) { return 1; } int[] value = new int[n + 1]; value[0] = 0; value[1] = 1; for (int i = 2; i <= n; i++) { //前提:(a + b) % p = (a % p + b % p) % p value[i] = (value[i - 1] + value[i - 2]) % 1000000007; } return value[n]; }
-
复杂度分析:
- 时间复杂度:O(n) 。
- 空间复杂度:O(n)。
-
测试:
方法二:动态规划
-
思路:
第 n 项只与第 n-1 和第 n-2 项有关,因此只需要初始化三个整形变量 sum, a, b ,利用辅助变量 sum 使 a , b 两数字交替前进即可。
-
代码:
public int fib(int n) { if (n == 0) return 0; int a = 0, b = 1, sum; for (int i = 2; i <= n; i++) { sum = (a + b) % 1000000007; a = b; b = sum; } return b; }
-
复杂度分析:
- 时间复杂度:O(n) 。计算 f(n) 需循环 n次,每轮循环内计算操作使用 O(1) 。
- 空间复杂度:O(1) 。几个标志变量使用常数大小的额外空间。
-
测试: