1. 斐波那契数列应用广泛,对此数列的更好理解有助于我们算法的更进一步,并降低程序的时间复杂度,提高运行效率.
2. 斐波那契数列的应用(4种):
2.1 排列组合----经典例子:爬楼梯
""" 有一段楼梯有10级台阶,规定每一步只能跨一级或两级,要登上第10级台阶有几种不同的走法? 这就是一个斐波那契数列:登上第一级台阶有一种登法;登上两级台阶,有两种登法;登上三级台阶,有三种登法;登上四级台阶,有五种登法…… 1,2,3,5,8,13……所以,登上十级,有89种走法。 类似的,一枚均匀的硬币掷10次,问不连续出现正面的可能情形有多少种? 答案是(1/√5)*{[(1+√5)/2]^(10+2) - [(1-√5)/2]^(10+2)}=144种。 求递推数列a⑴=1,a(n+1)=1+1/a(n)的通项公式 由数学归纳法可以得到:a(n)=F(n+1)/F(n),将斐波那契数列的通项式代入,化简就得结果。 """
2.2 兔子数列----兔子繁殖问题
""" 斐波那契数列又因数学家列昂纳多·斐波那契以兔子繁殖为例子而引入,故又称为“兔子数列”。 一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有兔子都不死,那么一年以后可以繁殖多少对兔子? 我们不妨拿新出生的一对小兔子分析一下: 第一个月小兔子没有繁殖能力,所以还是一对 两个月后,生下一对小兔对数共有两对 三个月以后,老兔子又生下一对,因为小兔子还没有繁殖能力,所以一共是三对 幼仔对数=前月成兔对数 成兔对数=前月成兔对数+前月幼仔对数 总体对数=本月成兔对数+本月幼仔对数 可以看出幼仔对数、成兔对数、总体对数都构成了一个数列。这个数列有关十分明显的特点,那是:前面相邻两项之和,构成了后一项。 这个数列是意大利中世纪数学家斐波那契在<算盘全书>中提出的,这个级数的通项公式,除了具有a(n+2)=an+a(n+1)的性质外,
还可以证明通项公式为:an=(1/√5)*{[(1+√5)/2]^n-[(1-√5)/2]^n}(n=1,2,3,...) """
2.3 数列与矩阵(现在的我暂时用不上)
""" 对于斐波那契数列1、1、2、3、5、8、13、……。有如下定义 F(n)=F(n-1)+F(n-2) F(1)=1 F(2)=1 对于以下矩阵乘法 F(n+1) = (1,1 ) (F(n),F(n-1))T F(n) =(1,0 ) (F(n),F(n-1))T 它的运算就是右边的矩阵 (1,1)乘以矩阵(F(n),F(n-1)),右边的矩阵(1,0 ) 乘以矩阵(F(n),F(n-1)),得到: F(n+1)=F(n)+F(n-1) F(n)=F(n) 可见该矩阵的乘法完全符合斐波那契数列的定义 设矩阵A=第一行(1,1)第二行(1,0) 迭代n次可以得到:F(n+1) =A^(n) *( F(2),F(1))T= A^(n)*(1,1)T 这就是斐波那契数列的矩阵乘法定义。 另矩阵乘法的一个运算法则A^n(n为偶数) = A^(n/2)* A^(n/2),这样我们通过二分的思想,可以实现对数复杂度的矩阵相乘。 因此可以用递归的方法求得答案。 数列值的另一种求法: F(n) = [ (( sqrt ( 5 ) + 1 ) / 2) ^ n ] 其中[ x ]表示取距离 x 最近的整数。 """
2.4 斐波那契弧线(暂时用不上)
""" 斐波那契弧线,也称为斐波那契扇形线。第一,此趋势线以二个端点为准而画出,例如,最低点反向到最高点线上的两个点。
然后通过第二点画出一条“无形的(看不见的)”垂直线。然后,从第一个点画出第三条趋势线:38.2%, 50%和61.8%的无形垂直线交叉。 斐波纳契弧线,是潜在的支持点和阻力点水平价格。斐波纳契弧线和斐波纳契扇形线常常在图表里同时绘画出。支持点和阻力点就是由这些线的交汇点得出。 要注意的是弧线的交叉点和价格曲线会根据图表数值范围而改变,因为弧线是圆周的一部分,它的形成总是一样的。 """
绘制图形如右图:
3. 如何用代码求斐波那契数列(4种方法):
1).递归 效率最低,时间复杂度时间复杂度O(1.618^n)
def fib_recur(n): assert n >= 0, "n > 0" if n <= 1: return n return fib_recur(n-1) + fib_recur(n-2) for i in range(1, 20): print(fib_recur(i), end=' ')
PS:递归 进阶版
使用lru_cache可减少重复计算.
from functools import lru_cache class Solution: @lru_cache(10**8) def climbStairs(self, n): """ :type n: int :rtype: int """ if n == 1: return 1 elif n == 2: return 2 else: return self.climbStairs(n - 1) + self.climbStairs(n - 2)
2)循环 也是递推法,递增法,时间复杂度O(n)
def fib_loop(n): a, b = 0, 1 for i in range(n+1): a, b = b, a+b return a for i in range(20): print(fib_loop(i), end=' ')
3)生成器
def fib_loop_while(max): a, b = 0, 1 while max > 0: a, b = b, a+b max -= 1 yield a for i in fib_loop_while(10): print(i)
4)类实现内部魔法方法
class Fibonacci(object): """斐波那契数列迭代器""" def __init__(self, n): """ :param n:int 指 生成数列的个数 """ self.n = n # 保存当前生成到的数据列的第几个数据,生成器中性质,记录位置,下一个位置的数据 self.current = 0 # 两个初始值 self.a = 0 self.b = 1 def __next__(self): """当使用next()函数调用时,就会获取下一个数""" if self.current < self.n: self.a, self.b = self.b, self.a + self.b self.current += 1 return self.a else: raise StopIteration def __iter__(self): """迭代器的__iter__ 返回自身即可""" return self if __name__ == '__main__': fib = Fibonacci(15) for num in fib: print(num)
5) 矩阵 时间复杂度为 O(log n) (矩阵的话不太好理解,需要先提高数学素养)
import numpy def fib_matrix(n): res = pow((numpy.matrix([[1, 1], [1, 0]])), n) * numpy.matrix([[1], [0]]) return res[0][0] for i in range(10): print(int(fib_matrix(i)), end=' ') ### 2 # 使用矩阵计算斐波那契数列 def Fibonacci_Matrix_tool(n): Matrix = npmpy.matrix("1 1;1 0") # 返回是matrix类型 return pow(Matrix, n) # pow函数速度快于 使用双星好 ** def Fibonacci_Matrix(n): result_list = [] for i in range(0, n): result_list.append(numpy.array(Fibonacci_Matrix_tool(i))[0][0]) return result_list # 调用 Fibonacci_Matrix(10)
PS:因为幂运算可以使用二分加速,所以矩阵法的时间复杂度为 O(log n)
用科学计算包numpy来实现矩阵法 O(log n)
6) 公式求解 时间复杂度O(1)
首先,列出公式:
from math import sqrt def fibonacci(n): s = int(1/sqrt(5)*(pow(((1+sqrt(5))/2),n)-pow(((1-sqrt(5))/2),n))) return s for i in range(10): print(fibonacci(i))
转自:https://baike.baidu.com/item/斐波那契数列/99145?fr=aladdin#5
https://blog.csdn.net/JIEJINQUANIL/article/details/52422141
https://www.cnblogs.com/panlq/p/9307203.html
来自LeetCode的wikizero的回答