程序员面试中,经常会被问到斐波那契数列(Fibonacci Sequence)相关的问题(比如斐波那契查找算法)。也许你没有听过斐波那契这个词,但是你一定听过“黄金分割”[1]吧?
上面这张《蒙娜丽莎》(来自[2])就体现了黄金分割的思想,即较大部分和较小部分之比为为1.681(具体证明见[1])。
斐波那契数列具有和黄金分割类似的性质,在数学上常用F表示(F为Fibonacci的缩写),我们首先来看一组斐波那契数:
上面这组斐波那契数来自维基百科,下标表示项数。通过观察可以发现:从第3项开始,每一项都是前两项的之和,即:
从数学表达上看,斐波那契的形式并不复杂,下面将介绍如何通过编程计算出任意个数的斐波那契数值,包含python和C++两个版本。但是,下面的代码仅仅用于理解概念,其性能是非常差的,并不是优化过的版本!!!
1、python实现
实现通项计算的最简单方式是递归,实际上数据结构与算法的某些书籍中,就使用斐波那契数列作为例子来讲解什么是递归。
比如,目标是求F(10),即F(10)=F(9)+F(8),所以我们需要求F(9)和F(8);又因为F(9) = F(8) + F(7)。。。。。。F(3) = F(2) + F(1),结束。所以,递归的结束条件就是n = 2或者n = 1,因为F(1)和F(2)是初值。
def fibonacci(n):
"""
Args:
n: the n-th index
Returns:
fibonacci number
"""
if (n==1 or n==2):
return 1
return fibonacci(n-1) + fibonacci(n-2)
下面来使用timeit模块测量一下计算30项所需的时间:
mean_time = timeit.timeit(stmt="[1, 1] + [fibonacci(i) for i in range(3, 30)]",
setup="from __main__ import fibonacci",
number=10)/30
得到的时间是0.12765667999998792,需要注意的是上述代码并不是最优实现,感兴趣的朋友可以自己尝试优化一下,或参考相关资料。
2、C++实现
int fibonacci(int n) {
if (n == 0 || n == 1) {
return 1;
}
return fibonacci(n - 1) + fibonacci(n - 2);
}
参考:
【1】https://baike.baidu.com/item/黄金分割/115896?fr=aladdin
【2】https://www.sohu.com/a/277537778_488901