通过增加缓存优化斐波那契递归的冗余计算

一、python

斐波那契数列的递归实现存在大量的冗余计算。例如,为了计算fib(n),我们需要计算fib(n-1)和fib(n-2),但是在计算fib(n-1)的过程中,我们又会重复计算fib(n-2)。当n的值很大时,这种冗余计算会消耗大量的计算资源。

为了解决这个问题,我们可以使用一种称为“记忆化”(Memoization)的技术。记忆化是一种优化技术,它将之前计算的结果存储起来,以便在需要时重新使用,而不是重新计算。

在斐波那契数列的递归实现中,我们可以创建一个缓存(通常是一个字典或数组),用于存储已经计算过的斐波那契数。每次计算新的斐波那契数时,我们首先检查缓存中是否已经存在该结果。如果存在,我们直接返回缓存中的结果,避免了冗余计算。如果不存在,我们进行计算,并将结果存储在缓存中,以便将来使用。

以下是一个使用Python实现的带有记忆化的斐波那契数列递归函数:

def fibonacci(n, cache={}):if n in cache:return cache[n]elif n <= 2:cache[n] = 1else:cache[n] = fibonacci(n-1, cache) + fibonacci(n-2, cache)return cache[n]

在这个函数中,我们使用了一个名为`cache`的字典作为缓存。每次调用函数时,我们首先检查`n`是否已经在`cache`中。如果是,我们直接返回`cache[n]`。否则,我们计算`fibonacci(n)`,并将结果存储在`cache`中。注意,我们在递归调用`fibonacci(n-1, cache)`和`fibonacci(n-2, cache)`时也传递了`cache`,以便在这些递归调用中也可以使用缓存。

二、go

斐波那契数列的递归实现因为重复地计算了很多子问题而效率比较低。这是一个典型的动态规划问题,可以通过“备忘录”方法优化,即在递归过程中记录已经计算过的斐波那契数,避免重复计算。
这里给一个使用备忘录优化斐波那契计算的Go代码示例:

package mainimport ("fmt"
)// 计算斐波那契数列的函数,使用备忘录优化递归
func fibonacci(n int, memo map[int]int) int {// 如果这个值已经计算过,直接从备忘录中返回if val, found := memo[n]; found {return val}// 边界条件if n <= 1 {return n}// 递归计算result := fibonacci(n-1, memo) + fibonacci(n-2, memo)// 将计算结果保存到备忘录memo[n] = resultreturn result
}func main() {// 初始化备忘录,用于存储已经计算过的斐波那契数memo := make(map[int]int)// 计算并打印第10个斐波那契数fmt.Println(fibonacci(10, memo))
}

在本例中,备忘录 memo 是一个Go语言的映射(map),它的键(key)是正在计算的 n 的值,而值(value)是对应斐波那契数。在函数 fibonacci 中,如果我们发现已经计算过了,就直接返回存储在 memo 中的结果。如果没有计算过,我们就计算它,并将结果保存到 memo 中,以便后续使用。
这种方法显著减少了计算量,因为每个斐波那契数值只计算一次。递归函数现在有线性的时间复杂度 O(n),而不是没有优化的递归版本的指数时间复杂度。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/680353.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

肿瘤微环境异质性对治疗反应的影响(综述)

Influence of tumour micro-environment heterogeneity on therapeutic response | Nature 肿瘤的形成涉及肿瘤细胞与细胞外基质、肿瘤血管和免疫细胞的共同进化。肿瘤的成功生长和最终转移并不完全取决于肿瘤细胞的基因改变&#xff0c;还取决于这种突变在特定环境中带来的适…

AMD FPGA设计优化宝典笔记(3)控制集

控制集 1 控制集的个数要求 控制集 control set&#xff1a;因为 7 系列 FPGA&#xff0c;一个 slice 只能有一种控制集&#xff08;触发器的使用方式 比如有复位/有时钟使能等等&#xff09;&#xff0c;多了就会分布到不同的 slice 里&#xff0c; 所以代码尽量统一触发器的…

2.12 分支、循环练习

1、选择题 1.1、以下程序的输出结果是 A 。 main() { int k11,k22,k33,x15; if(!k1) x--; else if(k2) if(k3) x4; else x3; printf(“x%d\n”,x); } A x4 B x15 C x14 D x3 解析&#xff1a;if(!k1) x--; 检查 k1 是否为0。因为 k1 的值为1&#xff0c;所…

带你了解软件系统架构的演变

软件系统架构的演变是一个不断适应技术进步和业务需求变化的过程。从早期的单体架构到现代的微服务架构&#xff0c;软件架构经历了几个主要的演变阶段。以下是对这些演变阶段的概述&#xff0c;以及一些工作实践、项目复盘和职场感悟。 单体架构&#xff08;Monolithic Archi…

嵌入式Qt Qt Creator安装与工程介绍

一.Qt概述 什么是Qt&#xff1a;Qt是一个跨平台的C图形用户界面应用程序框架。它为应用程序开发者提供建立图形界面所需的所有功能。它是完全面向对象的&#xff0c;很容易扩展&#xff0c;并且允许真正的组件编程。 二.Qt Creator下载安装 下载地址&#xff1a;Index of /a…

如何编译zlib?

学习文章&#xff1a;windows zlib库编译步骤_nmake 编译 zlib-CSDN博客 记录关键步骤&#xff1a; 打开 执行&#xff1a; 先cd到该目录&#xff1a; C:\Users\xxx\Downloads\zlib-1.2.11\contrib\masmx86 (这是我的zlib源码的下载路径&#xff09; 执行bld_ml32.bat 再…

【每日一题】03 不同路径Ⅱ(DP2)

问题描述 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么从左上…

LeetCode.145. 二叉树的后序遍历

题目 145. 二叉树的后序遍历 分析 上篇文章我们讲了前序遍历&#xff0c;这道题目是后序遍历。 首先要知道二叉树的后序遍历是什么&#xff1f;【左 右 根】 然后利用递归的思想&#xff0c;就可以得到这道题的答案&#xff0c;任何的递归都可以采用 栈 的结构来实现&#…

Python||数据分析之pyecharts 绘图(词云、气泡)

1. echarts 和 Pyecharts 简介 1.1echarts 简介: • echarts 是一个使用 JavaScript 实现的开源可视化库,涵盖各行业图表,满足各种需求。 • echarts 遵循 Apache-2.0 开源协议,免费商用。 • ECharts 最初由百度团队开源,并于 2018 年初捐赠给 Apache 基金会,成为 AS…

速盾cdn:cdn布置节点需要服务器吗

CDN&#xff08;Content Delivery Network&#xff09;是一种通过在全球各地分布的服务器节点存储和传送静态和动态内容的系统。在CDN中&#xff0c;服务器节点被称为边缘节点&#xff0c;它们位于全球不同的地理位置&#xff0c;可以更接近最终用户&#xff0c;从而提供更快的…

【Tauri】(2):使用Tauri应用开发,使用开源的Chatgpt-web应用做前端,使用rust 的candle做后端,本地运行小模型桌面应用

视频演示地址 https://www.bilibili.com/video/BV17j421X7Zc/ 【Tauri】&#xff08;2&#xff09;&#xff1a;使用Tauri应用开发&#xff0c;使用开源的Chatgpt-web应用做前端&#xff0c;使用rust 的candle做后端&#xff0c;本地运行小模型桌面应用 1&#xff0c;做一个免…

自定义Exporter开发--实现自己应用的监控--国产数据库通用模块开发

概述 Exporter是Prometheus监控系统中一个重要组件&#xff0c;可以理解为收集监控对象各种数据的agent。Prometheus为我们提供了较多的官方及第三方export&#xff0c;如果想要实现用户自己应用的监控&#xff0c;则需自己开发exporter,常用的监控对象大致可分为数据库对象&a…

ClickHouse--03--数据类型

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 数据类型1. Int2.FloattoFloat32(...) 用来将字符串转换成 Float32 类型的函数toFloat64(...) 用来将字符串转换成 Float64 类型的函数 3.DecimaltoDecimal32(value…

Linux常用make命令

一、简介 make 是一个常用的命令行工具&#xff0c;用于自动化构建和管理软件项目。它通常用于编译源代码、生成可执行文件或库&#xff0c;并处理项目中的依赖关系。 make 命令使用一个名为 “Makefile” 的文件来定义构建规则和目标。Makefile 中包含了一系列规则&#xff0…

视觉开发板—K210自学笔记(五)

本期我们来遵循其他单片机的学习路线开始去用板子上的按键控制点亮LED。那么第一步还是先知道K210里面的硬件电路是怎么连接的&#xff0c;需要查看第二节的文档&#xff0c;看看开发板原理图到底是按键是跟哪个IO连在一起。然后再建立输入按键和GPIO的映射就可以开始变成了。 …

Redis中缓存问题

缓存预热 Redis缓存预热是一项关键任务&#xff0c;可帮助提升应用程序的性能和响应速度。在高流量的应用程序中&#xff0c;Redis缓存预热可以加速数据查询和读取&#xff0c;从而改善用户体验。本文将介绍一种快速、稳定的Redis缓存预热方案&#xff0c;并提供相应代码实现。…

Linux第48步_编译正点原子的出厂Linux内核源码

编译正点原子的出厂 Linux 内核源码&#xff0c;为后面移植linux做准备。研究对象如下&#xff1a; 1)、linux内核镜像文件“uImage” 路径为“arch/arm/boot”&#xff1b; 2)、设备树文件“stm32mp157d-atk.dtb” 路径为“arch/arm/boot/dts” 3)、默认配置文件“stm32m…

django中实现数据库操作

在Django中&#xff0c;数据库操作通常通过Django的ORM&#xff08;Object-Relational Mapping&#xff09;来实现。ORM允许你使用Python类来表示数据库表&#xff0c;并可以使用Python语法来查询和操作数据库。 以下是在Django中实现数据库操作的基本步骤&#xff1a; 一&am…

2.11 假期作业

1、若有以下说明语句&#xff1a;int a[12]{1,2,3,4,5,6,7,8,9,10,11,12};char c’a’,d,g;则数值为4的表达式是&#xff08;D&#xff09;。 A&#xff09;a[g-c] B&#xff09;a[4] C&#xff09;a[‘d’-‘c’] D&#xff09;a[‘d’-c] 2、假…

C++入门篇——类与对象重点解析(中篇)

1. 类的6个默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 空类中真的什么都没有吗&#xff1f;并不是&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。 class Date {}; 默认成员函数&#xff1a;用户没有显式实现&a…