【算法】【动态规划】斐波那契数模型

【算法】【动态规划】斐波那契数模型

目录

一、动态规划解题模版

  1. 状态表示:我们一般创建一个一维数组dp,把dp表填满,其中的某一个值就是结果。而状态表示就是指这个dp表中元素的含义;
    1.1. 来源:题目要求,经验+题目要求 ,分析问题的过程中的重复子问题
  2. 状态转移方程:dp[ i ] = ?
  3. 初始化:保证根据状态转移方程填表时不越界
  4. 填表顺序:为了填写当前状态的时候,所需要的状态已经计算过了
  5. 返回值:题目要求 + 状态表示

二、第N个泰波那契数

题目链接:第N个泰波那契数
题目描述:

  • 第四个数是钱三个数的和,第一二三个数定下位0 1 1,返回第n个数


题目解析:

解题思路:

  1. 状态表示:dp[ i ] 表示的 i 个泰波那锲数
  2. 状态转移方程:dp[ i ] = dp[ i - 1] + dp[ i - 2] + dp[ i - 3]
  3. 初始化:dp[ 0 ] = 0, dp[ 1 ]= 1, dp[ 2 ] = 1
  4. 填表顺序:顺序从左向右填表即可
  5. 返回值: dp[ n ]

解题代码:

//时间复杂度:O(N)//空间复杂度:O(N)classSolution{publicinttribonacci(int n){if(n <3)return n ==0?0:1;//创建dp表int[] dp =newint[n +1];//初始化 dp[0]=0; dp[1]= dp[2]=1;//填表for(int i =3; i <= n; i++){ dp[i]= dp[i-1]+ dp[i-2]+ dp[i-3];}//返回值return dp[n];}}

空间优化:只创建长度为三的数组即可:

//时间复杂度:O(N)//空间复杂度:O(1)classSolution{publicinttribonacci(int n){if(n <3)return n ==0?0:1;//创建dp表int[] dp =newint[]{0,1,1};//填表for(int i =3; i <= n; i++){int tmp = dp[0]; dp[0]= dp[1]; dp[1]= dp[2]; dp[2]= tmp + dp[0]+ dp[1];}//返回值return dp[2];}}

三、⾯试题 08.01. 三步问题

题目链接:⾯试题 08.01. 三步问题](https://leetcode.cn/problems/three-steps-problem-lcci/description/)

题目描述:

题目解析:

  • 每一次上楼梯有三个选择: 1 2 3 ,返回走 到第n阶梯 步有多少种走法

解题思路:

  1. 状态表示:dp[ i ] 表示第 i 阶的上楼方式种类数
  2. 状态转移方程:dp[ i ] = dp[ i - 1] + dp[ i - 2] + dp[ i - 3]
  3. 初始化:dp[ 0 ] = 1, dp[ 1 ]= 1, dp[ 2 ] = 2 (小孩有3种走法,那么小孩的上一个台阶的可能就是 i-1, i-2, i-3 )
  4. 填表顺序:顺序从左向右填表即可
  5. 返回值: dp[ n ]

解题代码:

//时间复杂度:O(N)//空间复杂度:O(N)classSolution{publicintwaysToStep(int n){if(n <3)return n;//建立dp表int[] dp =newint[n+1];//初始化 dp[0]= dp[1]=1; dp[2]=2;//填表for(int i =3; i <= n; i++){ dp[i]=((dp[i-1]+ dp[i-2])%1000000007+ dp[i-3])%1000000007;}//返回值return dp[n];}}

四、746. 使⽤最⼩花费爬楼梯(easy)

题目链接:746. 使⽤最⼩花费爬楼梯(easy)

题目描述:

题目解析:

  • 给我们一个cost数组,表示走出这一个台阶需要的花费,
  • 可以选择第一步从cost[ 0 ] 还是 cost [ 1 ]开始。
  • 让我们返回到达楼顶的最小总花费。

解题思路:

  1. 状态表示:dp[ i ] 表示走到第 i 阶的最小花费
  2. 状态转移方程:dp[ i ] = dp[i-1]+cost[i-1] 和 dp[i-2]+cost[i-2] 的较小值
  3. 初始化:表的长度要比cost大1,表示楼顶
  4. 填表顺序:顺序从左向右填表即可
  5. 返回值: dp[ n ]
    解题代码:
//时间复杂度:O(N)//空间复杂度:O(N)classSolution{publicintminCostClimbingStairs(int[] cost){int n = cost.length;if(n ==2)returnMath.min(cost[0],cost[1]);//状态转移表int[] dp =newint[n+1];//状态转移方程for(int i =2; i <= n; i++){ dp[i]=Math.min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2]);}return dp[n];}}

五、91.解码⽅法

题目链接:91.解码⽅法

题目描述:

题目解析:

  • 给我们一个编码规则,数字1 - 26 对应表示字母A - Z
  • 给我们一个纯数字的字符串,让我们将字符串进行拆分,拆分后的字符串,对应的所有子串都可以对应表示成字母
  • 求可以拆分的种数

解题思路:

  1. 状态表示:dp[ i ] 表示字符串中 0 到 i 字符的合法拆分结果
  2. 状态转移方程:
    2.1. i 位置上字符为 1 到 9 的字符 单独解码成功 dp[ i ] += dp[ i - 1]
    2.2. i 与 i-1位置上的字符组合是 10 到 26 的合法编码 dp[ i ] += dp[ i-2 ]
  3. 初始化:
    3.1. dp[ 0 ] :第一个字符不为0,就dp[ 0] = 1,为0就返回0
    3.2. dp[ 1 ]:该字符不为0,dp[ 1 ] += dp[ 0 ],与第0个字符组成合法编码10 - 26 ,dp[ 1 ] += 1;

填表顺序:从左到右
返回值:dp[ n-1 ]

解题代码:

classSolution{publicintnumDecodings(String s){//前导0if(s.charAt(0)=='0')return0;int n = s.length();char[] ch = s.toCharArray();//只有一个字符if(n ==1)return1;int[] dp =newint[n];//初始化 dp[0]=1;//初始化第二个元素if(ch[1]!='0'&& ch[0]!='0') dp[1]+=1;int t =(ch[1]-'0')+(ch[0]-'0')*10;if(t >=10&& t <=26) dp[1]+=1;//填表for(int i =2; i < n; i++){//该字符单独组if(ch[i]!='0') dp[i]+= dp[i-1];//与前一个字符组 t =(ch[i]-'0')+(ch[i-1]-'0')*10;if(t >=10&& t <=26) dp[i]+= dp[i-2];}return dp[n-1];}}

Read more

程序员崩溃瞬间:这4道链表题不会,面试直接凉凉?速补!!

程序员崩溃瞬间:这4道链表题不会,面试直接凉凉?速补!!

坚持用清晰易懂的图解+多语言代码,让每道题变得简单! 🌟 🚀呆头个人主页详情 🌱呆头个人Gitee代码仓库 📌 呆头详细专栏系列 座右铭:“不患无位,患所以立。” 👨‍💻 程序员崩溃瞬间:这4道链表题不会,面试直接凉凉?速补!! * 前言 * 目录 * 1.移除链表元素 * 方法思路 * 代码实现 * 代码解释 * 2.反转链表 * 方法思路 * 代码实现 * 代码解释 * 3.查找链表中间结点 * 方法思路 * 代码实现 * 代码解释 * 4.合并两个有序链表 * 方法思路 * 代码实现 * 代码解释 * 为什么不需要循环就能连接所有剩余节点? 前言 🚀 你好,欢迎来到《编程闯关记》! 这里是算法与数据结构的实战基地,也是你从“暴力解法”到“最优解”的进化场。 🔍 专栏初衷: * 用清晰的图解 + 多语言代码(Python/

By Ne0inhk
详解数据结构之跳表

详解数据结构之跳表

目录 跳表的定义 跳表的演化过程 跳表的优化思路 跳表如何保证效率 跳表的时间复杂度 跳表的空间复杂度 跳表的查找 跳表的插入 跳表的删除 跳表的模拟实现 跳表与平衡搜索树及哈希表的对比 跳表的定义 跳表是由William Pugh(音译为威廉·普)发明的,最早出现于他在1990年发表的论文《Skip Lists: A Probabilistic Alternative to Balanced Trees》,跳表全称为跳跃列表,它允许快速查询,插入和删除一个有序连续元素的数据链表。 跳表的演化过程 对于单链表来说,即使数据是已经排好序的,想要查询其中的一个数据,只能从头开始遍历链表,这样效率很低,时间复杂度很高,是 O(n),如下图所示。 那我们有没有什么办法来提高查询的效率呢?我们可以为链表建立一个“索引”,这样查找起来就会更快,如下图所示,我们在原始链表的基础上,每两个结点提取一个结点建立索引,我们把抽取出来的结点叫作索引层或者索引,down

By Ne0inhk
Transformer实战(9)——Transformer分词算法详解

Transformer实战(9)——Transformer分词算法详解

Transformer实战(9)——Transformer分词算法详解 * 0. 前言 * 1. 子词分词算法 * 2. 加载预训练分词器 * 3. 常见字词分词算法 * 3.1 字节对编码 * 3.2 WordPiece * 3.3 SentencePiece * 4. 使用 tokenizers 库训练分词器 * 4.1 训练 BPE * 4.2 训练 WordPiece * 4.3 空分词管道 * 小结 * 系列链接 0. 前言 在自然语言处理领域,高效准确的分词算法是构建强大语言模型的基础。随着 Transformer 架构的广泛应用,子词分词算法已成为处理多语言文本和稀有词汇的关键技术。本文将从理论到实践,全面解析现代自然语言处理 (Natural Language Processing,

By Ne0inhk
计算机毕业设计Python+PySpark+Hadoop视频推荐系统 视频弹幕情感分析 大数据毕业设计(源码+文档+PPT+ 讲解)

计算机毕业设计Python+PySpark+Hadoop视频推荐系统 视频弹幕情感分析 大数据毕业设计(源码+文档+PPT+ 讲解)

温馨提示:文末有 ZEEKLOG 平台官方提供的学长联系方式的名片! 温馨提示:文末有 ZEEKLOG 平台官方提供的学长联系方式的名片! 温馨提示:文末有 ZEEKLOG 平台官方提供的学长联系方式的名片! 技术范围:SpringBoot、Vue、爬虫、数据可视化、小程序、安卓APP、大数据、知识图谱、机器学习、Hadoop、Spark、Hive、大模型、人工智能、Python、深度学习、信息安全、网络安全等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码、文档辅导、LW文档降重、长期答辩答疑辅导、腾讯会议一对一专业讲解辅导答辩、模拟答辩演练、和理解代码逻辑思路。 🍅文末获取源码联系🍅 🍅文末获取源码联系🍅 🍅文末获取源码联系🍅 感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及LW文档编写等相关问题都可以给我留言咨询,

By Ne0inhk