leetcode刷题(剑指offer) 509.斐波那契数

509.斐波那契数

斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 01 开始,后面的每一项数字都是前面两项数字的和。也就是:

F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1

给定 n ,请计算 F(n)

示例 1:

输入:n = 2
输出:1
解释:F(2) = F(1) + F(0) = 1 + 0 = 1

示例 2:

输入:n = 3
输出:2
解释:F(3) = F(2) + F(1) = 1 + 1 = 2

示例 3:

输入:n = 4
输出:3
解释:F(4) = F(3) + F(2) = 2 + 1 = 3

提示:

  • 0 <= n <= 30

题解:

这个题是简单的计算斐波那契数列,斐波那契数列就是, 1, 1, 2, 3, 5, 8。。。。这样的数列,从第二个开始,每个数都是它前面两个数的和。本文介绍这题的三种不同时间复杂度的解法,分别是递归实现O(n^2),迭代实现O(n),矩阵乘法实现O(logn)。

递归实现

这个就比较简单了,直接上代码,算法的复杂度是O(n^2)

public static int fib(int n) {if (n == 0) {return 0;}if (n == 1) {return 1;}return fib(n - 1) + fib(n - 2);
}

迭代实现

算法时间复杂度是O(n),和递归实现的区别是,总是记录了前两个值,相当于记忆性递归的效果。

代码如下:

public static int fib(int n) {if (n == 0) {return 0;}if (n == 1) {return 1;}// f(n - 1)int fn1 = 1;// f(n - 2)int fn2 = 0;int res = fn2 + fn1;for (int i = 3; i <= n; i++) {fn2 = fn1;fn1 = res;res = fn1 + fn2;}return res;
}

矩阵乘法实现

算法的时间复杂度是O(logn)。

首先引入矩阵相乘 ( F n F n − 1 F n − 1 F n − 2 ) ∗ ( 1 1 1 0 ) = ( F n + F n − 1 F n F n − 1 + F n − 2 F n − 1 ) (\begin{matrix}F_n&F_{n-1}\\F_{n-1}&F_{n-2}\end{matrix}) * (\begin{matrix}1&1\\1&0\end{matrix}) = (\begin{matrix}F_n + F{n-1}&F_n\\F_{n-1} + F_{n-2}&F_{n-1}\end{matrix}) (FnFn1Fn1Fn2)(1110)=(Fn+Fn1Fn1+Fn2FnFn1)

根据斐波那契迭代的公式可以推得

  • F n + F n − 1 = F n + 1 F_n + F_{n-1} = F_{n + 1} Fn+Fn1=Fn+1
  • F n = F n ​ F_n = F_n​ Fn=Fn
  • F n − 1 + F n − 2 = F n F_{n-1} + F_{n - 2} = F_n Fn1+Fn2=Fn
  • F n − 1 = F n − 1 F_{n-1} = F_{n-1} Fn1=Fn1

由此可以得出结论。

A n ∗ ( 1 1 1 0 ) = ( A n + 1 ) A_n * (\begin{matrix}1&1\\1&0\end{matrix}) = (A_{n+1}) An(1110)=(An+1)

只需要记录第n-1项,第n-2项,第n项,就可以使用乘法的方法来计算出第n+1项。

根据上式得到最终递推式如下:

A n = ( 1 1 1 0 ) n − 1 A_n = {(\begin{matrix}1&1\\1&0\end{matrix})}^{n-1} An=(1110)n1

到了这一步,直接使用矩阵乘法来计算的话,最终的时间复杂度为O(n)。但是乘法的话存在快速幂运算的计算方法,使用快速幂运算,可以将运算的时间复杂度进一步降低。

快速幂运算逻辑如下:

计算a的n次方,如果a是偶数,那就直接计算 a n / 2 ∗ a n / 2 a^{n/2} * a^{n/2} an/2an/2,如果是奇数就计算a乘上 a n − 1 a^{n-1} an1

代码如下:

public static int fib(int n) {if (n == 0) {return 0;} else if (n == 1) {return 1;}int[][] matrix = new int[][]{{1, 1},{1, 0}};matrix = powerMatrix(matrix, n - 1);return matrix[0][0];
}public static int[][] powerMatrix(int[][] matrix, int n) {if (n <= 1) {return matrix;} else if (n % 2 == 0){matrix = powerMatrix(matrix, n / 2);matrix = matrixMul(matrix, matrix);return matrix;} else {return matrixMul(matrix, Objects.requireNonNull(powerMatrix(matrix, n - 1)));}
}public static int[][] matrixMul(int[][] m1, int[][] m2) {int ROWS = m1.length;int COLS = m2[0].length;int[][] res = new int[ROWS][COLS];for (int i = 0; i < ROWS; i++) {for (int j = 0; j < COLS; j++) {int sum = 0;for (int k = 0; k < m1[0].length; k++) {sum += m1[i][k] * m2[k][j];}res[i][j] = sum;}}return res;
}

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

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

相关文章

Java玩转《啊哈算法》排序综合篇之小哼买书

是诸法空相&#xff0c;不生不灭&#xff0c;不垢不净&#xff0c;不增不减 非目录 缘起代码地址案例桶排序冒泡排序快速排序 缘起 各位大哥大姐&#xff0c;兄弟姐妹们好呀&#xff01;本人最近看了下《啊哈算法》&#xff0c;说来惭愧&#xff0c;买几年了&#xff0c;当初看…

Office提取某一页转成图片

目录结构 前言支持的文件格式代码整理maven依赖文本文档解析转换电子表格解析转换演示文档解析转换PDF解析转换小编代码整理(完整版)特别感谢扩展前言 近期公司需求,要将office文件提取第一页内容转成图片;一番调查后整理如下: 支持的文件格式 文本文档电子表格演示文档…

协会认证!百望云荣获信创工委会年度“卓越贡献成员单位”称号

当前&#xff0c;新一轮科技革命和产业变革正加速重塑全球经济结构&#xff0c;强化企业科技创新的主体地位&#xff0c;推动创新链、产业链、人才链深度融合&#xff0c;加快科技成果产业化进程至关重要。 近日&#xff0c;中国电子工业标准化技术协会信息技术应用创新工作委员…

HTTP中传输协议的数据格式

HTTP 概述&#xff1a;超文本传输协议(Hyper Text Transfer Protocol) 传输协议&#xff1a;定义了客户端和服务器通信时&#xff0c;发送数据的格式 客户端和服务器端交互&#xff1a;客户端向服务器端发送请求&#xff0c;服务器端向客户端响应请求 HTTP特点&#xff1a;…

安装mysql和navicat

1 安装mysql 以下是 MySQL 的安装教程: 步骤 1:下载 MySQL 首先在官方网站上下载 MySQL 安装包。在下载页面中选择第一个安装包,然后点击“下载”按钮,下载后解压缩。 下载地址 步骤 2:配置环境变量 配置MYSQL_HOME path 中添加%MYSQL_HOME%\bin 添加 my.ini ,内容…

1月威胁态势 | 0day占比83%!两大勒索家族“均分天下”

近日&#xff0c;亚信安全正式发布《亚信安全2024年1月威胁态势报告》&#xff08;以下简称“报告”&#xff09;报告显示&#xff0c;1月份新增安全漏洞1511个&#xff0c;涉及0day漏洞占83%&#xff1b;监测发现当前较活跃的勒索病毒家族是Wacatac和Nemucod&#xff0c;病毒样…

【C++】vector的简单使用和实现

vector就是我们之前数据结构学的顺序表&#xff0c;这篇博客就是说一说它的简单使用和底层实现 文章目录 简单使用模拟实现 简单使用 首先&#xff0c;我们看看它的构造函数 我们比较常用的也就是第二种&#xff0c;就是第一个参数是要存的数据个数&#xff0c;第二个是要填…

Python实现利用仅有像素级标注的json文件生成框标注的json文件,并存放到新文件夹

import json import os # create rectangle labels based on polygon labels, and store in a new folder def create_rectangle_shapes(polygon_shapes):rectangle_shapes []for polygon_shape in polygon_shapes:# 获取多边形的坐标点points polygon_shape[points]# 找到最…

node 第二十四天 mongoDB shell 命令 高级方法 $where aggregate聚合

$where 数据库数据如下 使用where语法如下 等价于 2.aggregate 聚合 使用聚合管道执行聚合操作。该管道允许用户通过一系列基于阶段的操作来处理来自集合或其他源的数据。 过滤数据, 分组数据 (排除name为 AAA 的数据 按price进行分组 每匹配一组计数1) 下面我们用aggregate…

新一轮范式转移的焦点:边缘

在万物互联的时代里 数据的洪流 正在慢慢转向边缘 &#x1f447;&#x1f447;&#x1f447; 当成千上万的设备接入互联网&#xff0c;大量数据正在边缘产生。在新一轮范式转移的过程中&#xff0c;边缘成为创建和处理数据的关键枢纽。企业该如何有效地管理边缘数据&#x…

Qt QWidget Loading界面并覆盖在其他控件上面

目录 一、效果图二、Loading三、使用 一、效果图 界面中有一个Label&#xff0c;一个Button 点击Buttion&#xff0c;显示Loading的界面&#xff0c;并覆盖到Label和Button上面 二、Loading loadingwidget.h #ifndef LOADINGWIDGET_H #define LOADINGWIDGET_H#include <…

Linux 网络配置及基础服务

目录 一. 查看网络配置信息的相关命令 1.1 ifconfig 命令 作用 1&#xff1a; 作用 2&#xff1a; 拓展&#xff1a; 1.2 ip/ethtool命令 1.3 hostname命令 1.4 route 命令 1.5 netstat 命令 1.6 ss&#xff08;socket statistics&#xff09;命令 1.7 ping 命令 …

小白级教程,10秒开服《幻兽帕鲁》

在帕鲁的世界&#xff0c;你可以选择与神奇的生物「帕鲁」一同享受悠闲的生活&#xff0c;也可以投身于与偷猎者进行生死搏斗的冒险。帕鲁可以进行战斗、繁殖、协助你做农活&#xff0c;也可以为你在工厂工作。你也可以将它们进行售卖&#xff0c;或肢解后食用。 前言 马上过年…

STM32——感应开关盖垃圾桶

STM32——感应开关盖垃圾桶 1.定时器介绍 软件定时 缺点&#xff1a;不精确、占用CPU资源 void Delay500ms() //11.0592MHz {unsigned char i, j, k;_nop_();i 4;j 129;k 119;do{do{while (--k);} while (--j);} while (--i); }定时器工作原理 使用精准的时基&#xff…

算法面试八股文『 基础知识篇 』

博客介绍 近期在准备算法面试&#xff0c;网上信息杂乱不规整&#xff0c;出于强迫症就自己整理了算法面试常出现的考题。独乐乐不如众乐乐&#xff0c;与其奖励自己&#xff0c;不如大家一起嗨。以下整理的内容可能有不足之处&#xff0c;欢迎大佬一起讨论。 PS&#xff1a;…

Redis常见问题

击穿 概念&#xff1a;在Redis获取某一key时, 由于key不存在, 而必须向DB发起一次请求的行为, 称为“Redis击穿”。 引发击穿的原因&#xff1a; 第一次访问恶意访问不存在的keyKey过期 合理的规避方案&#xff1a; 服务器启动时, 提前写入规范key的命名, 通过中间件拦截对…

Kotlin:用源码来深入理解 ‘StateFlow和SharedFlow的区别和联系‘

Kotlin&#xff1a;用源码来深入理解 ‘StateFlow和SharedFlow的区别和联系’ 在这篇文章中&#xff0c;我们将深入研究Kotlin中的StateFlow和SharedFlow&#xff0c;以及它们的相似之处和不同之处。我们将通过查看它们的源代码来理解它们的工作原理&#xff0c;这将帮助我们更…

【五】【C++】类与对象(三)

const只读 在 C 中&#xff0c;const 关键字用于声明一个变量为常量&#xff0c;意味着一旦被初始化之后&#xff0c;它的值就不能被改变。 声明常量&#xff1a; 使用 const 关键字可以声明变量为常量。这意味着这个变量的值不能被修改。 const int MAX_SIZE 100; 指针与…

Quartus生成烧录到FPGA板载Flash的jic文件

简要说明&#xff1a; Altera的FPGA芯片有两种基本分类&#xff0c;一类是纯FPGA&#xff0c;另一类是FPGASoc&#xff08;System on chip)&#xff0c;也就是FPGAHPS&#xff08;Hard Processor System&#xff0c;硬核处理器&#xff09;&#xff0c;对应两种Flash烧录方式&a…

【HTML】自定义属性(data)

自定义属性 data: 的用法&#xff08;如何设置,如何获取) &#xff0c;有何优势&#xff1f; data-* 的值的获取和设置&#xff0c;2种方法: 传统方法 getAttribute() 获取 data- 属性值; setAttribute() 设置 data- 属性值getAttribute() 获取 data- 属性值; setAttribute()…