题目描述
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。n<=39
一、斐波那锲数列
-
指的是这样一个数列: 1 、 1 、 2 、 3 、 5 、 8 、 13 、 21 、 34 、 … … 1、1、2、3、5、8、13、21、34、…… 1、1、2、3、5、8、13、21、34、……
-
在数学上,斐波纳契数列以如下被以递推的方法定义: F ( 1 ) = 1 , F ( 2 ) = 1 , F ( n ) = F ( n − 1 ) + F ( n − 2 ) ( n > = 3 , n ∈ N ∗ ) F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*) F(1)=1,F(2)=1,F(n)=F(n−1)+F(n−2)(n>=3,n∈N∗)
f ( n ) = { 0 n = 0 1 n = 1 f ( n − 1 ) + f ( n − 2 ) n > 1 f(n)=\begin{cases} 0 &n=0\\ 1&n=1\\ f(n-1)+f(n-2) & n>1 \end{cases} f(n)=⎩⎪⎨⎪⎧01f(n−1)+f(n−2)n=0n=1n>1
二、解题思路
本题根据数学公式很容易想到用递归的方法:
public class Solution {
public int Fibonacci(int n) {
if(n == 0){
return 0;
}
if(n == 1){
return 1;
}
return Fibonacci(n-1) + Fibonacci(n-2); //递归调用
}
}
从上图很容易看出,这种方法的运行时间比较长,我们仔细分析下,如果我们要计算 f ( 10 ) f(10) f(10),就要计算 f ( 9 ) f(9) f(9) 和 f ( 8 ) f(8) f(8),计算 f ( 9 ) f(9) f(9),就要计算 f ( 8 ) f(8) f(8) 和 f ( 7 ) f(7) f(7),可以发现,这里 f ( 8 ) f(8) f(8) 被重复计算了,随着 n n n 的增大,需要重复计算的急剧增加,这意味着计算量也会随着 n n n 的增大而急剧增大。
为了避免重复计算,最好的方法就是,我们将已经计算好的项先保存起来,在下次计算的时候,我们先查找下,如果前面已经计算过了就不用再重复计算了。
递归是将一个问题划分成为多个子问题求解,动态规划也是如此,但是动态规划会把子问题的解缓存起来,从而避免重复计算。
public class Solution {
public int Fibonacci(int n) {
if(n <= 1){
return n;
}
int[] result = new int[n + 1]; //存储每项结果,填充0
result[1] = 1;
for(int i = 2; i <= n; i++){
result[i] = result[i - 1] + result[i - 2];
}
return result[n];
}
}
相比递归的方法,此方法运行时间大大减少,因为要存储所有的计算结果,此时的空间复杂度为 O ( n ) O(n) O(n)
进一步我们根据公式可以发现,第 n n n 项,只与第 n − 1 n-1 n−1 项和第 n − 2 n-2 n−2 项有关,因此我们只需要存储前面两项的值就可以,这样空间复杂度由 O ( n ) O(n) O(n) 降低的 O ( 1 ) O(1) O(1):
public class Solution {
public int Fibonacci(int n) {
if(n <= 1){
return n;
}
int[] tmp = {0, 1}; //存储前两次结果
int result = 0; //本次结果
for(int i = 2; i <= n; i++){
result = tmp[0] + tmp[1];
//更新前两次结果
tmp[0] = tmp[1];
tmp[1] = result;
}
return result;
}
}
时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1)
三、Java
代码
public class Solution {
public int Fibonacci(int n) {
if(n <= 1){
return n;
}
int[] tmp = {0, 1}; //存储前两次结果
int result = 0; //本次结果
for(int i = 2; i <= n; i++){
result = tmp[0] + tmp[1];
//更新前两次结果
tmp[0] = tmp[1];
tmp[1] = result;
}
return result;
}
}
四、C++
代码
class Solution {
public:
int Fibonacci(int n) {
if(n <= 1){
return n;
}
int tmp[] = {0, 1};
int result = 0;
for(int i = 2; i <= n; i++){
result = tmp[0] + tmp[1];
tmp[0] = tmp[1];
tmp[1] = result;
}
return result;
}
};
五、Python3
代码
# -*- coding:utf-8 -*-
class Solution:
def Fibonacci(self, n):
# write code here
if n <= 1:
return n
tmp = [0, 1]
result = 0
for i in range(2, n + 1):
result = tmp[0] + tmp[1]
tmp[0] = tmp[1]
tmp[1] = result
return result