问题描述
查找斐波纳契数列中第 N 个数。
所谓的斐波纳契数列是指:
- 前2个数是 0 和 1 。
- 第 i 个数是第 i-1 个数和第i-2 个数的和。
- 斐波纳契数列的前10个数字是:0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ...
- N <= 20
样例
样例 1:
输入: 1
输出: 0
样例解释:返回斐波那契的第一个数字,是0.
样例 2:
输入: 2
输出: 1
样例解释: 返回斐波那契的第二个数字是1.
解题思路
根据题目描述,我们可以获得数列的通项公式:an=an-1+an-2;
简单的用递归/递推就能完成(在n非常大的情况下,递归会出现超时)。
代码示例(JAVA)
1. 递归
public class Solution {
/**
* @param n: an integer
* @return: an ineger f(n)
*/
public int fibonacci(int n) {
if (n <= 2) {
return n == 1 ? 0 : 1;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
时间复杂度:O(2^n)
空间复杂度:O(n)
解释:
在求解fib(10)的时候,会找到fib(9)和fib(8)共两个,然后下一层会是fib(8)和fib(7),fib(7)和fib(6)共四个;这是一条底数为2呈指数增长的曲线。
2. 递推
public class Solution {
/**
* @param n: an integer
* @return: an ineger f(n)
*/
public int fibonacci(int n) {
// write your code here
int[] fib= new int[n];
for (int i = 0; i < n; i++) {
if (i <= 1) {
fib[i] = i == 0 ? 0 : 1;
}
else {
fib[i] = fib[i - 1] + fib[i - 2];
}
}
return fib[n - 1];
}
}
时间复杂度:O(n)
空间复杂度:O(n)
解释:
这里理解起来比较简单,不再赘述。对比递归算法,相当于加了一个缓存。
但是,空间复杂度可以再优化:可以从数列的通项公式看出,计算每个数时,只和前两个数有关,更前面的数已经不再使用了;因此,我们可以只使用长度为2的数组。
优化后代码如下:
public class Solution {
/**
* @param n: an integer
* @return: an ineger f(n)
*/
public int fibonacci(int n) {
// write your code here
int[] fib= {0, 1};
for (int i = 2; i < n; i++) {
fib[i % 2] = fib[0] + fib[1];
}
return fib[(n + 1) % 2];
}
}
网友评论