剑指 Offer 10- I. 斐波那契数列 (从重叠子问题到备忘录到dp数组迭代解法)

目录

  • 题目描述
  • 1、暴力递归法的重叠子问题
  • 2、备忘录解法
  • 3、dp数组迭代算法
  • 4、滚动数组优化
  • 5、参考链接

题目描述

写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项。斐波那契数列的定义如下:

F(0) = 0, F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.
斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

1、暴力递归法的重叠子问题

暴力递归法最为常见,但是同时它的时间复杂度也是最高的,附带了许多重复计算。

class Solution {
public:int fib(int n) {if(n==0) return 0;else if(n == 1 || n == 2) return 1;else return (fib(n - 1) + fib(n - 2))%1000000007;}
};

画出递归树:
在这里插入图片描述
算法时间复杂度为递归二叉树结点总数,为O(2^n)。f(18)、f(17)被重复计算了,并且以f(18)为根节点的递归树体积也是十分巨大的,如果再算一遍会耗费大量的时间。
这个问题性质我们可以描述为“重叠子问题”。

2、备忘录解法

既然是重复计算的问题,我们就可以构造一个备忘录。
每次计算出某个子问题的答案先别着急返回,先记到备忘录中再返回;
每次遇到一个子问题,先去备忘录中查找,如果已经解决了这个问题,就直接把答案拿过来用,不再进行计算。

class Solution {
public:int search_helperTab(vector<int >& helperTab,int n){//n较小的直接返回if(n == 1 || n == 2) return 1;//如果已经计算过了,直接返回计算过的值if(helperTab[n] != 0) return helperTab[n];//如果没有计算过,则需要重新计算一遍else{helperTab[n] = (search_helperTab(helperTab,n-1) + search_helperTab(helperTab,n-2))%1000000007;}return helperTab[n];}int fib(int n) {if(n==0) return 0;//构建一个备忘录vector<int >helperTab(n+1,0);return search_helperTab(helperTab,n);}
};

带备忘录的递归算法,将一颗存在巨量冗余的递归树剪枝为没有冗余的递归图。
递归算法时间复杂度=子问题个数 * 解决子问题所需要的时间。
由于不存在冗余计算,所以子问题个数为O(n);解决一个子问题的时间是O(1);
所以本算法的时间复杂度是O(n)。
注意,我们刚刚画的递归树是从上向下延伸的,都是从一个规模较大的原问题,向下逐渐分解规模,直到触底(f(1)、f(2)),然后逐层返回答案,这就是自顶向下。

如果直接从最底下的最小规模的f(1)、f(2)开始往上推导,直到f(20),这就是动态规划的思路。

3、dp数组迭代算法

class Solution {
public:int fib(int n) {if(n==0) return 0;if(n == 1 || n == 2) return 1;//构建一个备忘录vector<int >dp(n+1,0);dp[1]=dp[2]=1;for(int i = 3;i <= n;i++)dp[i]=(dp[i-1]+dp[i-2])%1000000007;return dp[n];}
};

4、滚动数组优化

状态方程中的当前状态只由前两个状态决定,所以不需要一个数组进行存放。

class Solution {
public:int fib(int n) {if(n==0) return 0;if(n == 1 || n == 2) return 1;int pre=1,curr=1;for(int i = 3;i <= n;i++){int sum=(pre+curr)%1000000007;pre=curr;curr=sum;}return curr;}
};

这样空间复杂度就降到O(1)了。

5、参考链接

剑指 Offer 10- I. 斐波那契数列
labuladong:动态规划详解(修订版)

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

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

相关文章

C# 收邮件

C#没有内置收邮件的类&#xff0c;参考网络上的代码&#xff0c;针对POP3协议服务器使用 Jmail组件来收邮件&#xff0c;针对IMAP协议服务器使用LumiSoft.Net 。 另外&#xff0c;一般免费邮箱需要在邮箱设置中开启 POP3&#xff08;或IMAP&#xff09;、 SMTP服务才可以使用非…

HDU- 1754 I Hate It

http://acm.hdu.edu.cn/showproblem.php?pid1754 记住那让自己wa的地方。 I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 29300 Accepted Submission(s): 11615 Problem Description很多学校流行…

mcq 队列_MCQ | 软件生命周期模型

mcq 队列Q1. Which of the following models is best suited when the requirements of the software are not decided and also the user is not sure about how he wants the user interface to look like? Q1。 当不确定软件的需求并且用户不确定自己希望用户界面看起来如何…

十、纺织品库存管理系统全部功能展示

一、系统主页面—Form1 系统运行加载页面&#xff0c;主要包含三个功能&#xff0c;①登录、②注册、③退出系统 程序运行图&#xff1a; 登录功能&#xff0c;跳转到登录页面 注册功能&#xff0c;跳转到注册页面 退出系统&#xff0c;程序结束运行 代码如下&#xff1a; …

leetcode 376. 摆动序列 思考分析

目录题目思路分析代码总结题目 如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称为摆动序列。第一个差&#xff08;如果存在的话&#xff09;可能是正数或负数。少于两个元素的序列也是摆动序列。 例如&#xff0c; [1,7,4,9,2,5] 是一个摆动序列&am…

[EF在VS2010中应用Entity framework与MySQL

在VS2010中应用Entity framework与MySQL 罗朝辉 (http://www.cnblogs.com/kesalin/) 本文遵循“署名-非商业用途-保持一致”创作公用协议本文讲述了在VS2010中使用EF与MySQL的一个简单示例。 工具安装&#xff1a; 1&#xff0c;MySQL MySQL Community Server Connector/NET 6…

c++ cdi+示例_C ++“和”关键字示例

c cdi示例"and" is an inbuilt keyword that has been around since at least C98. It is an alternative to && (Logical AND) operator and it mostly uses with the conditions. “ and”是一个内置关键字&#xff0c;至少从C 98起就存在。 它是&&am…

Python上个手

Python&#xff0c;由吉多范罗苏姆&#xff08;Guido van Rossum&#xff09;在1989打发圣诞节放假时间的一门“课余”编程项目&#xff0c;至今已有二十多年的历史&#xff0c;语法简洁清晰&#xff0c;深受喜爱&#xff1b; 小窥 # 查看版本 python -V # 输出 print "he…

十、美化界面

一、背景图片 二、透明化处理 BackColor—web—Transparent 三、数据库建表语句 数据库 USE [fiber_yy] GO /****** Object: Table [dbo].[yy_user_record] Script Date: 06/20/2022 18:54:48 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADD…

如何写出优美的代码(二)

&#xff08;本文思想基本来自于经典著作《重构》一书&#xff09; 上一篇 http://www.cnblogs.com/ceys/archive/2012/03/05/2379842.html#commentform 上一篇文章主要讲了怎么给函数整容。现在我们大家基本上都使用面向对象语言&#xff0c;什么样的“对象”才是优美的呢&…

转:链表相交问题 详解

源地址&#xff1a;http://blog.163.com/bbluesnow126/blog/static/27784545201251051156817/ 链表相交问题 2012-06-10 17:15:37| 分类&#xff1a; 算法 | 标签&#xff1a;微软面试题 |字号 订阅 1、如何判断一个单链表有环 2、如何判断一个环的入口点在哪里 3、如何知…

VS 如何修改C++编译标准

第一步&#xff0c;打开项目资源管理器的属性页面 第二步&#xff0c;选择配置属性->C/C>语言->C语言标准 第三步&#xff0c;选择合适的标准&#xff0c;一般来说选最新即可

维吉尼亚密码和一次性密码本_密码学中的一次性密码

维吉尼亚密码和一次性密码本The One-time Pad cipher is almost similar to the Vernam cipher, as, like the vernam cipher, this cipher technique also encrypts the plain text by working on the binary level of the text. The only difference between the two is that…

十一、纺织面料下架功能的实现

一、数据库 数据库仍用yy_textile表&#xff0c;前几篇博文都叙述过这里就不再叙述 在fiber_yy数据库下创建yy_textile表 初始数据库信息 二、页面 admin_undercarriage 三、代码实现 admin_undercarriage using System; using System.IO; using System.Data; using S…

svg和canvas的应用场景分析【转载】

原文地址&#xff1a;http://blogs.msdn.com/b/weizhong/archive/2011/07/16/canvas-svg.aspx 思考什么时候使用Canvas 和SVG wzhong 15 Jul 2011 9:07 PM 0HTML5 Canvas 和 SVG 是 IE9 中引入的两项令人激动的图形功能。上周在拉斯维加斯举办的 MIX11 大会对这两个功能进行了介…

【C++grammar】文件系统以及path类使用

目录1.文件系统概述1、关于路径2、如何将某个路径下的所有文件递归地找出来&#xff1f;2.路径类及操作1、path类的成员函数2、path类的非成员函数示例1&#xff1a;展示C17中的path对象的用法示例2&#xff1a;展示Path类中用于分解路径成分的函数示例3&#xff1a;展示path相…

scala hashmap_如何在Scala中将Hashmap转换为Map?

scala hashmapLets first understand what are maps and hashmaps? 首先让我们了解什么是map和hashmap &#xff1f; map in Scala is a collection that stores its elements as key-value pairs, like a dictionary. Scala中的map是一个集合&#xff0c;将其元素存储为键值…

十二、所有功能实现效果演示

一、系统项目架构 Ⅰ&#xff0c;fiber_yy数据库下有五张表 yy_admin&#xff1a;管理员登录账号和密码 yy_textile&#xff1a;纺织面料数据信息 yy_textile_record&#xff1a;用户购买纺织面料信息所存储的面料流水信息 yy_user&#xff1a;用户登录注册信息 yy_user_reco…

行业软件之PTV微观软件VISSIM4.3 5.0 5.1 5.2 5.3 5.4下载和相关资料

他是干什么的&#xff1a;http://baike.baidu.com/view/3656765.htm 中国代理销售的公司的网址&#xff1a;辟途威交通科技(上海)有限公司 官网&#xff1a;http://www.ptvchina.cn/ 看看视频中软件的运行效果&#xff1a;http://v.youku.com/v_show/id_XMzExMjg1MDEy.html 如何…

一、单个神经元网络构建

一、本人使用编译器为Jupyter Notebook&#xff0c;tensorflow版本为1.13.1 import tensorflow as tf print(tf.__version__) """ 1.13.1 """二、训练单个神经元网络 x为-1.0, 0.0, 1.0, 2.0, 3.0, 4.0 y为-3.0, -1.0, 1.0, 3.0, 5.0, 7.0 人用…