【算法题】神奇的斐波那契数列(Fibonacci sequence)、青蛙跳台阶问题、矩阵中的路径

news2025/1/10 11:43:46

神奇的斐波那契数列和青蛙跳台阶问题

  • 一、神奇的斐波那契数列
    • 1.1、题目描述
    • 1.2、递归算法
    • 1.3、迭代法
    • 1.4、小结
  • 二、青蛙跳台阶问题
    • 2.1、题目描述
    • 2.2、思路
    • 2.3、动态规划法
    • 2.4、小结
  • 三、矩阵中的路径
    • 3.1、题目描述
    • 3.2、思路
    • 3.3、代码实现
    • 3.4、小结
  • 总结

一、神奇的斐波那契数列

1.1、题目描述

写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(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:

输入:n = 2
输出:1

示例 2:

输入:n = 5
输出:5

来源:力扣(LeetCode)

1.2、递归算法

递归算法实现斐波那契数列。

int Fibonacci(int n)
{
	if (n <= 0)
		return 0;
	if (n == 1 || n == 2)
		return 1;

	return Fibonacci(n - 1) + Fibonacci(n - 2);
}

如果是leetcode上测试,会提示超时。

斐波那契数列的通项公式:
FIC

这里可以看到,时间复杂度属于爆炸增量函数。

1.3、迭代法

只需要第n个斐波那契数,中间结果只是为了下一次使用,不需要保存。所以,可以采用迭代法。

class Solution {
public:
    int fib(int n) {
        if(n<=0)
            return 0;
        else if(n==1 || n==2)
            return 1;
        int f1=1;
        int f2=1;
        for(int i=3;i<=n;i++)
        {
            int tmp=f1+f2;
            f1=f2;
            f2=tmp%1000000007;
        }
        return f2;
    }
};

leetcode上测试是,答案需要取模 1e9+7(1000000007)。

时间复杂度:O(n)。
空间复杂度:O(1)。

1.4、小结

除了迭代法将时间复杂度降到了O(n),还有一种数学公式方式,使用矩阵快速幂将时间复杂度降到O(log n)。
在这里插入图片描述

二、青蛙跳台阶问题

2.1、题目描述

一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。

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

示例 1:

输入:n = 2
输出:2

示例 2:

输入:n = 7
输出:21

示例 3:

输入:n = 0
输出:1

来源:力扣(LeetCode)

2.2、思路

这个和斐波那契数列(Fibonacci sequence)非常相似。像这种求多少种可能性的题目一般都有递推性质,即f(n)和f(n-1)…f(1)之间是有联系的;即 f(n)=f(n-1)+f(n-2)。可转化为 求斐波那契数列第n项的值 ,唯一的不同在于起始数字不同。

青蛙跳台阶问题: f(0)=1 , f(1)=1 , f(2)=2。

斐波那契数列问题: f(0)=0 , f(1)=1 , f(2)=1 。

青蛙跳台问题

2.3、动态规划法

动态规划解析:

状态定义: 设 dp 为一维数组,其中 dp[i]的值代表 斐波那契数列第 i个数字 。

转移方程: dp[i + 1] = dp[i] + dp[i - 1],即对应数列定义 f(n + 1) = f(n) + f(n - 1);

初始状态: dp[0] = 1, dp[1] = 1 ,即初始化前两个数字;

返回值: dp[n],即斐波那契数列的第 n 个数字。

class Solution {
public:
    int numWays(int n) {
        if(n<2)
            return 1;
        int a=0,b=1,c=1;
        for(int i=2;i<=n;i++)
        {
            a=b;
            b=c;
            c=(a+b)% 1000000007;

        }
        return c;
    }
};

时间复杂度 O(N)。

空间复杂度 O(1)。

2.4、小结

像这种求多少种可能性的题目一般都有递推性质,优先考虑动态规划算法。

三、矩阵中的路径

3.1、题目描述

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。

单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。

例如,在下面的 3×4 的矩阵中包含单词 “ABCCED”(单词中的字母已标出)。
在这里插入图片描述

示例 1:

输入:board = [[“A”,“B”,“C”,“E”],[“S”,“F”,“C”,“S”],[“A”,“D”,“E”,“E”]], word = “ABCCED”
输出:true

示例 2:

输入:board = [[“a”,“b”],[“c”,“d”]], word = “abcd”
输出:false

来源:力扣(LeetCode)

3.2、思路

典型的矩阵搜索问题,可使用深度优先搜索(DFS)+ 回溯剪枝解决。
在这里插入图片描述

DFS递归参数:board数组及其行号 i 和列号 j ,word字符串及当前目标字符在word中的索引 k 。

DFS递归终止条件:

返回false:行号超出索引范围、列号超出索引范围、当前board的字符board[i][j]不等于目标字符word[k]。
返回true:字符串word已全部匹配,即k = len(word) - 1。

递推过程和防止错误:

  1. 标记当前矩阵元素: 将 board[i][j] 修改为空字符 ‘\0’,代表此元素已访问过,防止之后搜索时重复访问而出现错误。
  2. 朝当前元素的上、下、左、右四个方向开启下层递归,使用或连接 (代表只需找到一条可行路径就直接返回,不再做后续 DFS ),并记录结果。
  3. 还原当前矩阵元素, 将 board[i][j] 元素还原至初始值,即 word[k] 。为什么还原是word[k]?因为如果board[i][j] != word[k]就已经被终止递归返回false了,不会运行到下面。

3.3、代码实现

class Solution {
private:
    int rows, cols,n;
    bool dfs(vector<vector<char>>& board, string word,int i,int j,int k)
    {
        if(i<0 || j<0 || i>=rows || j>=cols || board[i][j]!=word[k])
            return false;
        if(k==n-1)
            return true;
        board[i][j]='\0';
        bool ret=dfs(board,word,i,j-1,k+1) || dfs(board,word,i,j+1,k+1) 
                || dfs(board,word,i-1,j,k+1) || dfs(board,word,i+1,j,k+1);
        board[i][j]=word[k];
        return ret;
    }
public:
    bool exist(vector<vector<char>>& board, string word) {
        rows=board.size();
        cols=board[0].size();
        n=word.size();
        for(int i=0;i<rows;i++)
        {
            for(int j=0;j<cols;j++)
            {
                if(dfs(board,word,i,j,0))
                    return true;
            }
        }
        return false;
    }
};

时间复杂度: O ( 3 K M N ) O(3^K MN) O(3KMN) 。最差情况下,需要遍历矩阵中长度为K字符串的所有方案,时间复杂度为 O ( 3 K ) O(3^K) O(3K) ;矩阵中共有MN个起点,时间复杂度为 O(MN) 。

空间复杂度O(K):搜索过程中的递归深度不超过K。

3.4、小结

矩阵搜索问题,可使用深度优先搜索(DFS)+ 回溯剪枝解决。只要理清楚这几点:

  1. 解决搜索时重复访问问题。
  2. 递归的中止条件,也叫剪枝。
  3. 递归的参数。
  4. 递归发散的方向。

总结

一定要做好总结,特别是当没有解出题来,没有思路的时候,一定要通过结束阶段的总结来反思犯了什么错误。解出来了也一定要总结题目的特点,题目中哪些要素是解出该题的关键。不做总结的话,花掉的时间所得到的收获通常只有 50% 左右。

在题目完成后,要特别注意总结此题最后是归纳到哪种类型中,它在这种类型中的独特之处是什么。
在这里插入图片描述

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

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

相关文章

卫星地图应用经典实例项目(7个)

本文会介绍引用一些非常好的卫星地图等相关的应用,一方面给大家增加见识,另一方面会提供一些设计开发的思路以及代码。 文章目录 热气球追踪系统googlemap实现卫星轨迹satvis卫星Cesium系统NASA的worldview系统项目Esri-Satellite-Map基于leaflet的卫星轨迹绘制项目地球当前…

关于Altium Designer 差分线规则设置的方法纠偏

本文适用于AD20以后版本。在AD的原理图及pcb的4年设计学习中&#xff0c;入门课是学校的AD09&#xff0c;简单的两层板绘制。后来因工作需要&#xff0c;就报了培训班&#xff0c;学习了基于AD19的相关使用方法。后来在很多的项目开发中&#xff0c;逐渐发现之前从书本、培训课…

Qt QGraphicsScene模块实现圆点绘制在所有窗体的最前方,实现圆点的“彩色拖尾”效果以及“选中方框”效果

文章目录 前言1、效果2、代码实现2.1 思路2.1.1 “拖尾”效果2.1.2 “选中方框区域”效果2.2 代码 总结 系列文章&#xff1a; &#xff08;一&#xff09;Qt 将某控件、图案绘制在最前面的方法&#xff0c;通过QGraphicsScene模块实现 &#xff08;二&#xff09;Qt QGraphics…

【SCI/SSCI/EI录用案例】仅26天录用,1天见刊

【Unionpub学术】录用/见刊/检索案例&#xff1a;2023年6月10日-2023年6月16日 2区材料类SCI 【期刊简介】IF:3.5-4.0&#xff0c;JCR2区&#xff0c;中科院3区 【检索情况】SCI 在检&#xff0c;正刊 【征稿领域】降解材料及其相关技术的研发&#xff0c;如聚合物基轻质材…

PyTorch 2简介:卷积神经网络

介绍 在本系列的上一部分中&#xff0c;我们使用了CIFAR-10数据集&#xff0c;并介绍了PyTorch的基础知识&#xff1a; 张量及其相关操作数据集和数据加载器构建基本的神经网络基本模型的训练和评估 我们为CIFAR-10数据集中的图像分类开发的模型只能在验证集上达到53%的准确率&…

Observability:为 Logstash 输出配置 SSL/TLS - Elastic Agent

在我之前的文章 “Observability&#xff1a;如何把 Elastic Agent 采集的数据输入到 Logstash 并最终写入到 Elasticsearch”&#xff0c;我详细介绍了如何使用 Elastic Agents 采集数据并把数据通过 Logstash 发送至 Elasticsearch。细心的开发者可能注意到从 Elastic Agents…

Jmeter(三) - 从入门到精通 - 测试计划(Test Plan)的元件(详解教程)

1.简介 上一篇中我已经教你如何通过JMeter来创建一个测试计划&#xff08;Test Plan&#xff09;&#xff0c;那么这一篇我们就将JMeter启动起来&#xff0c;创建一个测试计划&#xff08;Test plan&#xff09;&#xff0c;然后现在给大家介绍一下测试计划&#xff08;Test P…

Redis和数据库保持数据一致性方案

Redis和数据库一致性又称为“双写一致性”&#xff0c;在分布式系统中&#xff0c;由于多个节点之间的并发读写操作&#xff0c;可能导致数据不一致的情况发生。本文将着重介绍如何通过使用Redis与数据库相结合的方案来实现数据一致性。 数据不一致产生的原因&#xff1a; 首先…

Android应用开发(5)Activity生命周期

Android应用开发学习笔记——目录索引 参考android官网&#xff1a; https://developer.android.google.cn/reference/android/app/Activity.html activity 生命周期的阶段 | Android 开发者 | Android Developers activity生命周期&#xff08;这篇足够了&#xff09;_…

pycharm中插件的使用;

pycharm中插件的使用&#xff1b; 1.英语翻译插件 Translation 使用方法 在pycharm中输入英文&#xff0c;右键&#xff0c;例如输入port想知道这个意思&#xff0c; 中文 也是一样的 2.pycharm的中文界面插件&#xff0c;安装后就是中文界面了

VSCode编译器环境下,调试3d-tiles-validator

VSCode编译器环境下&#xff0c;调试3d-tiles-validator 1. 源代码环境准备2. VsCode环境装备3. 调试 1. 源代码环境准备 参照3d-tiles-validator仓库的README.md文件 Clone the repository into the current directory:git clone https://github.com/CesiumGS/3d-tiles-vali…

Dubbo3.0.7+Nacos2.0.3整合服务注册及发现

Dubbo3的新特性和修改这里就不再赘述了&#xff0c;个人认为主要是注册的颗粒度的改变&#xff0c;把之前的接口级改成了应用级&#xff0c;减少了注册列表的数量更易于维护。 服务端&#xff1a; pom.xml <dependencies><dependency><groupId>org.spring…

前端系列19集-vue3引入高德地图,响应式,自适应

npm i amap/amap-jsapi-loader --save import AMapLoader from amap/amap-jsapi-loader // 使用加载器加载JSAPI&#xff0c;可以避免异步加载、重复加载等常见错误加载错误 //为地图注册click事件获取鼠标点击出的经纬度坐标 map.on("click", function (e: any) { …

30分钟了解所有引擎组件,132个Unity 游戏引擎组件速通!【收藏 == 学会】

前言 &#x1f3ac;【全网首发】 | 30分钟了解所有组件&#xff0c;132个Unity 游戏引擎组件速通&#xff01;一、Mesh 网格1.Mesh Filter2.Mesh Renderer3.Skinned Mesh Renderer4.Text Mesh5.TextMeshPro-Text 二、Effects 特效组件1.Particle System2.Visual Effect3.Trail …

一篇一个CV模型,第(1)篇:StyleGAN

写在前面&#xff1a; 虽说自己肯定对外宣称自己是搞CV的&#xff0c;但是其实在自己接近两年半(&#x1f414;)的研究生生涯中&#xff0c;也没有熟练掌握过很多个CV领域的模型&#xff0c;或者说是CV领域的概念。我认为这个东西是必须得补的&#xff0c;不然作为CV算法工程师…

嵌入式应用复习知识点总结

一.期末考试题型 1.单选题40’2.判断题10’3.简答题20’4.综合设计题&#xff08;66108&#xff09; 二.单选题知识点 1.嵌入式系统 1.定义 IEEE&#xff08;国际电气和电子工程师协会&#xff09;的定义&#xff1a; Devices used to control, monitor, or assist the op…

CDN能防住攻击吗?

&#x1f482; 个人网站:【海拥】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 目录 前言什么是CDN&#xf…

撸一遍STM32最小系统板

采样的MCU型号为STM32F405RGT6&#xff0c;目前这款芯片价格便宜性能好。 1 电机控制会用到单片机的哪些功能&#xff1f; GPIO&#xff08;通用输入/输出&#xff09;&#xff1a;单片机的GPIO引脚可以用于控制电机的开关、使能以及接收传感器的反馈信号。通过设置GPIO引脚的…

机器学习强基计划9-2:图解字典学习KSVD算法(附Python实战)

目录 0 写在前面1 字典学习2 问题形式化3 KSVD算法4 Python实现 0 写在前面 机器学习强基计划聚焦深度和广度&#xff0c;加深对机器学习模型的理解与应用。“深”在详细推导算法模型背后的数学原理&#xff1b;“广”在分析多个机器学习模型&#xff1a;决策树、支持向量机、…

基于Java+Swing实现的代码统计工具

基于JavaSwing实现的代码统计工具 一、系统介绍二、功能展示三、代码展示四、其他系统五、获取源码 一、系统介绍 系统可以统计C&#xff0c;C&#xff0c;Java代码的空行、注释、有效代码行数 使用说明 直接运行main方法即可 运行环境&#xff1a;idea jdk 二、功能展示 …