当前位置: 首页 > news >正文

fibonacci的4种实现

文章目录

    • 工具函数
    • 1. base递归
    • 2. 数组缓存计算结果
    • 3. 自底向上迭代替换递归
    • 4. 终极解法,根据状态推导式 f(n) = f(n-1) + f(n-2) 只保留要前两个状态

fibonacci的4种实现.把n=0也考虑在内

工具函数

计算运行时间与内存

def time_memory(func):@functools.wraps(func)def wrapper(*args, **kwargs):tracemalloc.start()start = time.perf_counter()res = func(*args, **kwargs)duration = (time.perf_counter() - start)*1000current, peak = tracemalloc.get_traced_memory()tracemalloc.stop()print(f"{func.__name__} excution duration: {duration:.3f} ms")print(f"{func.__name__} memory usage: current = {current / 1024:.3f} KB, peak = {peak / 1024:.3f} KB")return resreturn wrapper

1. base递归

最简单的递归实现,此种实现分线下来会有非常多重复子问题计算,导致时间复杂度为O(2^n)指数级别.

def fibonacci_base(n: int):if n < 0:raise ValueError(f'{n} is invalid')elif n == 0:return 0elif n == 1:return 1else:return fibonacci_base(n-1) + fibonacci_base(n-2)

测试样例

@time_memory
def test_base(n: int):res = fibonacci_base(n)print(res)test_base(18)

运行结果

test_base excution duration: 3.812 ms

2. 数组缓存计算结果

考虑到base解法有不少重复计算的数值,可以用一个数组存放已经计算好的数值,递归计算时可以查看数组里面是否有之前已经计算好的值,使用空间换时间的方法,算法时间复杂度O(N) 空间复杂度O(N)

def do_fibonacci_e1(n: int, buffer: list[int]):if n < 0:raise ValueError(f'{n} is invalid')if n == 0:return buffer[0]elif n == 1:if buffer[1] == 0:buffer[1] = 1return buffer[1]else:if buffer[n] == 0:buffer[n] = do_fibonacci_e1(n-1, buffer) + do_fibonacci_e1(n-2, buffer)return buffer[n]def fibonacci_e1(n: int):if n < 0:raise ValueError(f'{n} is invalid')else:buffer = [0] * (n+1)return do_fibonacci_e1(n, buffer)

测试样例

@time_memory
def test_e1(n: int):res = fibonacci_e1(n)print(res)test_e1(18)

运行结果

test_e1 excution duration: 0.097 m

3. 自底向上迭代替换递归

自底向上的解决办法,使用循环替代递归,时间复杂度O(N) 空间复杂度O(N) 循环实现消耗资源更少,所以时间更快.
代码:

def fibonacci_e2(n: int):if n < 0:raise ValueError(f'{n} is invalid')elif n == 1:return 1# n >= 2 开始构建数组dp = [0]*(n+1)dp[0] = 0dp[1] = 1for i in range(2, n+1):dp[i] = dp[i-1] + dp[i-2]return dp[n]

测试样例

@time_memory
def test_e2(n: int):res = fibonacci_e2(n)print(res)test_e2(18)

运行结果

test_e2 excution duration: 0.052 ms

4. 终极解法,根据状态推导式 f(n) = f(n-1) + f(n-2) 只保留要前两个状态

进一步将时间复杂度降低到O(1)

def fibonacci_e3(n: int):if n < 0:raise ValueError(f'{n} is invalid')elif n == 1:return 1pre = 0curr = 1for i in range(2, n+1):res = pre + currpre = currcurr = resreturn res

测试样例

@time_memory
def test_e3(n: int):res = fibonacci_e3(n)print(res)

运行结果

test_e3 excution duration: 0.040 ms
http://www.dtcms.com/a/290907.html

相关文章:

  • Unity之可视化编程VisualScripting快速入门
  • 1553啤酒品牌作为都洲武魂世界格斗冠军赛冠名赞助商
  • Jenkins pipeline触发下游流水线
  • 数据结构:反转字符串(Reversing a String)
  • 052_迭代器(Iterator / ListIterator)
  • HCL 三层知识总结
  • Java 二叉树
  • uniapp+vue3预约时间和日期
  • registry-ui docker搭建私有仓库的一些问题笔记
  • 在React中做过哪些性能优化?
  • java每日精进 7.21【Uel表达式和流程设计】
  • 【Elasticsearch】IndexModule
  • 【沧海拾昧】微分先行PID与中间微分反馈控制
  • 工业网关的应用场景
  • 【正常配置了beast扩展,phpinfo信息也显示了,但是就是不运行】
  • 前端-DOM
  • pandas 的series和dataframe的用法,六个题目
  • 141、环形链表
  • 前后端分离项目进阶1---后端
  • 果园里的温柔之手:Deepoc具身智能如何重塑采摘机器人的“生命感知”
  • Python day20 - 特征降维之奇异值分解
  • 【设计模式C#】工厂方法模式(相比简单工厂模式更加具有灵活性和扩展性的工厂模式)
  • git_guide
  • prometheus主动服务发现机制
  • 在 React 中实现全局防复制hooks
  • Java 解析前端上传 ZIP 压缩包内 Excel 文件的完整实现方案
  • Neo4j 5.x版本的导出与导入数据库
  • 易语言+懒人精灵/按键中控群控教程(手机、主板机、模拟器通用)
  • CFD总压边界条件的理解与开发处理
  • DM8数据库Docker镜像部署最佳实践