《剑指Offer》
题目描述
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
n<=39
知识背景:
斐波那契数列,又称黄金分割数列,指的是这样一个数列:
1、1、2、3、5、8、13、21、……
由此可看出这样的一个特征,从第三项开始,此项的数值=前两项的数值之和。
在数学上,斐波纳契数列以如下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N*)
由此可相处最简单的实现方法
1、递归实现
图示
def Fibonacci(n):
if n == 0:
return 0
if n == 1:
return 1
if n > 1:
num = Fibonacci(n-1)+Fibonacci(n-2)
return num
// 若输入的数值小于0则返回空值
return None
时间复杂度为二叉树节点个数:(2h)-1=O(2N) ,空间复杂度为树的高度:h即O(N)。
参考文章:斐波那契数列的递归与循环实现及复杂度分析
虽然实现简单,但时间复杂度太高,来优化一下。
2、非递归实现
首先,观察数列情况:
1、1、2、3、5、8、13、21、……
可发现每次新的一项都是由前两项相加而得,只要设置两个变量去存储紧挨着的两项即可。
当 n = 0 时,为0
当 n = 1 时,为1
当 n > 1 时,为 f(n) = f(n-1) + f(n-2)
h = a + b
a为h的前一项,b为h的前两项。执行叠加次数受项数n约束,由于最前一项为n-2,因此所执行的次数应为n-2。
例如上图,由于每次相加减的数为三个数,当在滑动窗口下的数相加减,因此当滑动窗口移动到整个竖列最低端时,移动次数为n-2。
def Fibonacci(n):
if n == 0:
return 0
if n == 1:
return 1
a = 1
b = 0
ret = 0
for i in range(0,n-1)
ret = a +b
b = a
a = ret
return ret
时间复杂度为O(n)