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

news2024/11/19 3:24:36

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.coloradmin.cn/o/1417513.html

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

相关文章

读书笔记:九句耐人寻味的话

“情商一定是让别人和自己都舒服。如果让别人舒服&#xff0c;自己却很痛苦&#xff0c;那不叫情商&#xff0c;叫智障。” Emotional intelligence must be about making both others and oneself comfortable. If it makes others comfortable but oneself miserable, thats …

盛最多水的容器[中等]

一、题目 给定一个长度为n的整数数组height。有n条垂线&#xff0c;第i条线的两个端点是(i, 0)和(i, height[i])。找出其中的两条线&#xff0c;使得它们与x轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。也就是求x轴与y轴的面积。 说明&#xff1a;你不能倾…

Threejs 展示——obj 格式模型导入

文章目录 需求分析1. HTML版本2. Vue 版本 需求 导入obj 格式的模型数据 分析 .obj&#xff1a;Wavefront OBJ 格式&#xff0c;是一种广泛使用的三维模型文件格式。预览 .obj格式文件的软件可点此下载需要准备两种格式的数据&#xff0c;如下所示 1. HTML版本 html <!…

电脑和手机连接酒店的wifi,网络不通导致charles无法抓手机的包

查看苹果手机&#xff0c;连wifi后的ip地址 电脑去ping 手机的ip地址&#xff0c;发现ping不通 解决方案&#xff1a; 应该是酒店wifi的问题&#xff0c;让朋友开个手机热点&#xff0c;电脑和我的手机都连这个热点&#xff0c;就可以抓包了

13.Golang中面向对象的多态及基本要素

目录 概述实践多态实现代码结果 基本要素 结束 概述 Golang中类的表示与封装继承 用这种方式并不能实现多态 需要结合 interface 来实现。 实践 多态实现 代码 package mainimport "fmt"type AnimalIF interface {// 这两个方法&#xff0c;实现类&#xff0c;必…

python笔记10

1、继承 继承是面向对象编程中的一个重要概念&#xff0c;它允许一个类&#xff08;子类&#xff09;继承另一个类&#xff08;父类&#xff09;的属性和方法。通过继承&#xff0c;子类可以重用父类的代码&#xff0c;并且有机会添加新的属性和方法&#xff0c;或者重写父类的…

【C++】一题掌握空指针

今天看见一道面试题&#xff0c;比较有意思&#xff0c;这一分享出来&#xff1a; 1.下面程序能编译通过吗&#xff1f; 2.下面程序会崩溃吗&#xff1f;在哪里崩溃 class A {public:void PrintA(){cout<<_a<<endl;}void Show(){cout<<"Show()"&…

.ui文件相关

目录 ui类生成过程&#xff1a; 提问&#xff1a; 等以后自己熟练了用代码写这些样式内容&#xff0c;尽量用代码写&#xff0c;原因很简单&#xff1a; 用代码写的可以直接修改代码&#xff0c;但是在设计界面修改的东西&#xff0c;电脑没有QC这玩意&#xff0c;还真不好改…

ChatGPT4 比 ChatGPT3.5 强在了那里?

刚开始的时候我还在纠结&#xff0c;一个月20 刀的ChatGPT4 &#xff0c;到底值不值这个价钱&#xff1f;使用过后发现&#xff0c;诶嘛真香。因为 GPT4 比 GPT3.5 多了太多功能&#xff0c;特别是识图能力&#xff0c;用好的话效率翻倍。 1. 看图写代码 ChatGPT4 相比 ChatG…

【极数系列】Flink集成DataSource读取集合数据(07)

文章目录 01 引言02 简介概述03 基于集合读取数据3.1 集合创建数据流3.2 迭代器创建数据流3.3 给定对象创建数据流3.4 迭代并行器创建数据流3.5 基于时间间隔创建数据流3.6 自定义数据流 04 源码实战demo4.1 pom.xml依赖4.2 创建集合数据流作业4.3 运行结果日志 01 引言 源码地…

用ASM HEMT模型提取GaN器件的参数

标题&#xff1a;Physics-Based Multi-Bias RF Large-Signal GaNHEMT Modeling and Parameter Extraction Flow (JEDS 17年) 模型描述 该模型的核心是对表面势&#xff08;ψ&#xff09;及其随施加的栅极电压&#xff08;Vg&#xff09;和漏极电压&#xff08;Vd&#xff09…

【数据结构1-3】集合

有时候&#xff0c;我们并不关心数据之间的前后关系&#xff0c;也不关心数据的层次关系。一些确定元素只是单纯的聚集在一起&#xff0c;这样的元素聚集体被称为集合。 当希望知道某个数据是否存在一个集合中&#xff0c;或者两个元素是否在同一个集合中时&#xff0c;就需要使…

JVM系列——对象管理

JVM对象分布 对象头 第一类是用于存储对象自身的运行时数据&#xff0c;如哈希码&#xff08;HashCode&#xff09;、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等 另外一部分是类型指针&#xff0c;即对象指向它的类型元数据的指针&#xff0c;Java 虚…

敲黑板啦!CSGO游戏搬砖项目操作注意事项

CSGO游戏搬砖项目怎么赚钱的&#xff0c;利润在哪&#xff1f; 1.两个平台之间币种不一样&#xff0c;就存在一个汇率差&#xff0c;两平台装备价格也不一样&#xff0c;汇率差-价格差利润。 CSGO游戏搬砖项目具体有哪些操作步骤&#xff1f; 1、准备一台电脑&#xff0c;配置…

Git学习,基础,安装,配置,笔记总结

Git安装与常用命令 本教程里的git命令例子都是在Git Bash中演示的,会用到一些基本的linux命令,在此为大家提前列举: ls/ll 查看当前目录 cat 查看文件内容 touch 创建文件 vi vi编辑器(使用vi编辑器是为了方便展示效果,学员可以记事本、editPlus、notPad++等其它编 辑…

C#使用OpenCvSharp4库读取电脑摄像头数据并实时显示

一、OpenCvSharp4库 OpenCvSharp4库是一个基于.Net封装的OpenCV库&#xff0c;Github源代码地址为&#xff1a;https://github.com/shimat/opencvsharp&#xff0c;里面有关于Windows下安装OpenCvSharp4库的描述&#xff0c;如下图所示&#xff1a; 二、C#使用OpenCvSharp4库…

React 组件生命周期-概述、生命周期钩子函数 - 挂载时、生命周期钩子函数 - 更新时、生命周期钩子函数 - 卸载时

React 组件生命周期-概述 学习目标&#xff1a; 能够说出组件的生命周期一共几个阶段 组件的生命周期是指组件从被创建到挂在到页面中运行&#xff0c;在到组件不用时卸载组件 注意&#xff1a;只有类组件才有生命周期&#xff0c;函数组件没有生命周期(类组件需要实例化&…

监听项目中指定属性数据,点击或模块显示时

当项目中&#xff0c;需要获取某个页面上、某个标签上、有指定自定义属性时&#xff0c;需要在点击该元素时进行公共逻辑处理&#xff0c;或该元素在显示的时候进行逻辑处理&#xff0c;这时可以定义一个公共的方法&#xff0c;在每个页面引用&#xff0c;并写入数据即可 &…

Win11系统连接带HDMI接口的显示器后,电脑没有声音如何调试

解决这个问题的方法很简单&#xff0c;没有那么复杂。之所以使用HDMI接口连接了显示器后没声音&#xff0c;原因就是HDMI接口是包含音频视频两种信号的接口。当电脑的HDMI接口被使用时&#xff0c;系统就会默认从HDMI设备输出声音信号了&#xff0c;而此时如果HDMI设备没有声音…

基本控件(二)QMainWindow主窗口相关 以及 手写控件的方法 (按F2)

探究过程 先创建个QMainWindow项目。 鼠标点击选中QMainWindow之后按F2&#xff0c;就会进入其最一开始的定义的头文件中。 来到qmainwindow.h头文件中&#xff0c;可以清楚看到这些继承关系&#xff1a; 同样的操作&#xff0c;来到QWidget的定义之处&#xff1a; UI设计界面…