精益求精——斐波那契数列的logn解法

简介: 精益求精——斐波那契数列的logn解法

缘起:兔子数列

斐波那契数列指的是这样一个数列:1,1,2,3,5,8,13,21,34,55,89...

这个数列从第3项开始,每一项都等于前两项之和。它因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”。

斐波那契数列递推公式:

斐波那契数列很强,在现代物理、准晶体结构、化学等领域,斐波那契数列都有直接的应用。

通常求解斐波那契数列的算法有递归算法和动态规划算法,递归算法直接利用斐波那契数列的递推公式求解,递归调用递推公式,使时间复杂度为指数阶,当数列元素很多时,求解过程将是一场灾难。再来看动态规划,它会动态存储运算过程中的结果,使时间复杂度降到了多项式阶,较递归算法好了很多,那有没有更好的算法呢,我们知道,多项式阶时间复杂度好于指数阶时间复杂度,而对数阶时间复杂度比多项式阶时间复杂度更为优越,那有没有对数阶时间复杂度的算法可以求解斐波那契数列呢?答案是:有,必须的,嘿嘿。

计算一个数的幂

在讲解斐波那契数列求解之前,我们先来看看怎么更好的求解一个数的连乘,即一个数的幂次。比如求一个数的n次幂,最简单的做法是先求前两个数的乘积,得到的结果再去乘以第三个数,得到乘积再去乘以第四个数,不断重复,一直到n个数都乘完。这看上去很自然,那它的时间复杂度是多少呢?很明显,是O(n),即多形式阶。

除了上面的方法,我们可以利用分治的思想,让n个数先两两相乘,得到的结果再两两相乘,可用递归算法求解,求解过程如下图所示

看,是不是二叉树的感觉出来了,很明显,有了类似树的结构,运算的时间复杂度就是O(logn)

具体计算公式如下

我们将数推广到矩阵,比如2x2阶矩阵,有类似的结论,只不过数的相乘就一次乘法运算,而两个2x2阶矩阵的相乘需要12次算术运算(相乘后的矩阵中,每个元素都需要两次乘法和一次加法获得),是两个数相乘所需运算量的12倍,但利用上面分治的思想,矩阵连乘运算的时间复杂度仍然是对数阶的。

数学归纳法

令P(n)是关于整数n的某个命题,假定我们需要证明P(n)对于所有正整数n为真,一种重要做法是:

(a) 证明P(1)为真;

(b) 证明“如果P(1),P(2)....P(n-1)全部为真,那么P(n)也为真”,这个证明应对任意正整数n成立.

这就是著名的数学归纳法。

斐波那契数列的恒等式

斐波那契数列满足许多有趣的恒等式,其中一个恒等式可以用矩阵来表示为

我们可以用数学归纳法证明这个公式:

当n=1,F0=0,F1=1,F2=2,等式成立。

现在假设n-1项斐波那契数列满足恒等式,即

证明n项斐波那契数列也满足恒等式,根据矩阵乘法的定义,我们可以得到

这个恒等式有什么用呢,结合上一小节的结论我们不难发现,通过这个恒等式,我们就将斐波那契数列的求解变成了一个特殊矩阵的连乘,这样会使时间复杂度变成对数阶!!哈哈,我们找到了可以求解斐波那契数列并且时间复杂度是对数阶的算法!!

代码

import numpy as np
 
# 特殊矩阵
A = np.array([[1, 1], [1, 0]])
 
 
def fibonacci(n):
    if n <= 1:
        return A
    # 根据恒等式求解特殊矩阵连乘
    multi = np.dot(fibonacci(n>>1), fibonacci(n>>1))
    return multi if n & 1 == 0 else np.dot(multi, A)
 
 
# 算法主体
def run():
    # 数列元素个数
    N = 11
    # 求解斐波那契数列
    result = fibonacci(N-1)
    print("斐波那契数列第{}项是:{}".format(N, result[0][0]))
 
 
if __name__ == "__main__":
    run()

程序运行结果如下

斐波那契数列第11项是:89

作者这水平有限,有不足之处欢迎留言指正

相关文章
|
10月前
|
消息中间件 NoSQL 架构师
招行面试:亿级秒杀,超卖问题+少卖问题,如何解决?(图解+秒懂+史上最全)
45岁资深架构师尼恩在读者交流群中分享了如何系统化解决高并发下的库存抢购超卖少买问题,特别是针对一线互联网企业的面试题。文章详细解析了秒杀系统的四个阶段(扣库预扣、库存扣减、支付回调、库存补偿),并通过Redis分布式锁和Java代码示例展示了如何防止超卖。此外,还介绍了使用RocketMQ延迟消息和xxl-job定时任务解决少卖问题的方法。尼恩强调,掌握这些技术不仅能提升面试表现,还能增强实际项目中的高并发处理能力。相关答案已收入《尼恩Java面试宝典PDF》V175版本,供后续参考。
|
关系型数据库 MySQL
cmd中输入net start mysql 提示:服务名无效或者MySQL正在启动 MySQL无法启动
cmd中输入net start mysql 提示:服务名无效或者MySQL正在启动 MySQL无法启动
|
监控 关系型数据库 MySQL
守护进程到底是什么?如何创建?(图文并茂,你不得不看的一篇文章)
**守护进程(Daemon Process)详解**:守护进程是后台运行的无终端关联的系统进程,常在启动时启动,提供持续服务,如网络服务、日志记录和定时任务。其特点包括脱离终端、后台运行、持久服务、资源管理和错误处理。创建守护进程涉及重定向文件描述符、创建新会话、改变工作目录等步骤。`ps` 和 `top` 命令用于查看守护进程,前者提供进程快照,后者显示实时资源使用情况。
1404 0
|
11月前
|
人工智能 自然语言处理 API
自学记录HarmonyOS Next的HMS AI API 13:语音合成与语音识别
在完成图像处理项目后,我计划研究HarmonyOS Next API 13中的AI语音技术,包括HMS AI Text-to-Speech和Speech Recognizer。这些API提供了强大的语音合成与识别功能,支持多语言、自定义语速和音调。通过这些API,我将开发一个支持语音输入与输出的“语音助手”原型应用,实现从语音指令解析到语音响应的完整流程。此项目不仅提高了应用的交互性,也为开发者提供了广阔的创新空间。未来,语音技术将在无障碍应用和智慧城市等领域展现巨大潜力。如果你也对语音技术感兴趣,不妨一起探索这个充满无限可能的领域。 (238字符)
503 11
|
存储 缓存 JSON
详解HTTP四种请求:POST、GET、DELETE、PUT
【4月更文挑战第3天】
71134 5
详解HTTP四种请求:POST、GET、DELETE、PUT
element plus表格的表头和内容居中
element plus表格的表头和内容居中
947 0
|
资源调度 Kubernetes 应用服务中间件
Deployment的创建、滚动更新、回滚版本、扩容缩容
Deployment的创建、滚动更新、回滚版本、扩容缩容
544 1
|
机器学习/深度学习 人工智能 算法
|
人工智能 数据安全/隐私保护
如何实现AI检测与反检测原理
AI检测器用于识别AI生成的文本,如ChatGPT,通过困惑度和爆发性指标评估文本。低困惑度和低爆发性可能指示AI创作。OpenAI正研发AI文本水印系统,但尚处早期阶段。现有检测器对长文本较准确,但非100%可靠,最高准确率约84%。工具如AIUNDETECT和AI Humanizer提供AI检测解决方案,适用于学生、研究人员和内容创作者。
下一篇
oss云网关配置