当前位置:网站首页>力扣每日一题----求第n位斐波那契数
力扣每日一题----求第n位斐波那契数
2022-08-08 21:16:00 【从现在开始壹并超】
题目解析
方法一 暴力递归求解
这种方法其实就是使用递归的思想来求解,将每个数看成是一颗二叉树的节点,当且仅当找到二叉树的叶子节点(两个初始值0和1)时才结束循环,也就是递归的终止条件。画图说明,如下:
可以看出计算第n个节点的斐波那契数,即需要计算出整个二叉树每个节点的值,时间复杂度为2的n次方,非常庞大,代码见下。
方法二 暴力递归的优化
暴力递归求解中的时间复杂度如何去降低呢?可以发现,暴力递归需要计算上图中的每个二叉数节点的值,但是其中有一些值的计算是可以去除的,就是说存在大量的节点值的计算是冗余的。不难看出,当计算根节点时,需要计算节点4和节点3的值,但是计算节点4的值又需要计算节点3和节点2的值,如果左子树的值计算完毕,那么右子树的值就不要再去递归求解了,因此只需要计算图中的最长一条路径左中的节点的值,根节点的值自然可以求出。如下图,只需要计算红色路径上的值即可:
依次思路,只需要计算n个斐波那契数,时间复杂度可降低为O(n);
但是如何去得到每个节点的值呢?需要使用一个数组,来保存每次计算的节点值,最多只有n个值,那么空间复杂度为O(n)。
方法三 双指针思想
虽然方法二中去重递归可以将时间复杂度降低为O(n), 但是空间复杂度也为O(n),如何去降低这个空间复杂度呢?逐步求解某一个位置的元素值,并且是由某两个值来得到的,类似这种问题,都可以联想到双指针思想:
慢指针指向数组最左端,快指针指向数组下标为1的位置,逐步更新两个指针所指向的元素,直至遍历到第n个元素为止,即可得到第n个斐波那契数,此时的时间复杂度不变还是O(n),而空间上只有两个指针,并没有使用额外的空间,因此空间复杂度为O(1)。
代码解析
1. 暴力递归
public static int Fib1(int num) {
if (num == 0) {
return 0;
}
if (num == 1) {
return 1;
} else {
return Fib1(num - 1) + Fib1(num - 2);
}
}
2. 去重递归
public static int Fib2(int num) {
int[] arr = new int[num + 1]; //初始化全为0的整型数组,用来保存每次计算得到的Fib数值,避免重复计算
return resurse(arr, num);
}
private static int resurse(int[] arr, int nums) {
if (nums == 0) {
return 0;
}
if (nums == 1) {
return 1;
}
if (arr[nums] != 0) {
//如果该Fib数不为0表示之前已经计算过该值了,直接进行返回,对于第一次才计算的值才使用递归求解
return arr[nums];
}
arr[nums] = resurse(arr, nums - 1) + resurse(arr, nums - 2);
return arr[nums];
}
注意:这里的arr数组初始化为全0的整数数组,因为后面当第一次计算某个斐波那契数时才需要进行递归求解,否则,当某个斐波那契数被计算得到了,此时已经存在数组arr的某个位置处,这个元素就不再是0了。当下一次再使用该值时,就不要再一次进行计算,直接返回该值即可。
3. 双指针求解
public static int Fib3(int num) {
int low = 0, high = 1;
if (num == 0) {
return 0;
}
if (num == 1) {
return 1;
}
for (int i = 2; i <= num; i++) {
int sum = low + high;
low = high;
high = sum;
}
return high;
}
定义两个指针:慢指针指向数组下标0,快指针指向数组下标1,同上设定两个default也就是两个斐波那契的初始值。从下标位置2开始循环,将上一次的元素进行加和得到当前的斐波那契数sum,更新两个指针:快指针所指向的值赋值给慢指针low,当前得到的斐波那契数sum赋值给快指针high,进行下一次求解,直至循环到第num个元素结束。最后直接返回快指针high即可,low指针保存的是上一个斐波那契数。
边栏推荐
- 中国石油大学(北京)-《 油田化学》第三阶段在线作业
- 关闭MySQL自动提交
- position的值,relative和absolute分别相对谁定位
- H5 移动端调取手机相机或相册
- Under the Windows socket (TCP) console program
- Property or method “XXX“ is not defined on the instance but referenced during render.
- 1个不为人知的 Jupyter notebook 使用技巧,今天分享出来。
- 文件上传接入阿里云OSS
- MySQL8.0设置远程访问权限
- 【Voice of dreams】
猜你喜欢
- project experience 】 【 conservation projects
IDEA Error:(1, 1) 错误: 非法字符: \65279 Error:(1, 10) 错误: 需要class, interface或enum 解决办法
6万人砍不下来一部拼多多手机,背后原来是这个原因。
Centos下载安装redis- 使用yum
Centos安装Redis --使用wget
国足1-3不敌越南后,9000人在重温范志毅的“神预言”!
MATLAB:方程组的求解
数组的push()、pop()、shift()和unshift()方法讲解
MySQL8.0设置远程访问权限
汤加火山爆发引发跨洋海啸?数据可视化告诉你真实威力!
随机推荐
Redis之持久化机制
H5页面调用手机打电话功能
Members that must be initialized for initial column initialization
Redis之sorted set 命令
《第一行代码(第二版)》学习中百分比布局依赖导入问题
ES6新特性未命名参数
小程序模拟淘宝京东商品轮播滑动展示功能模块
复合索引使用
GeoServer入门学习:07-发布多层级TIF地图大图数据
用Multisim对石英晶体振荡器进行仿真
蚂蚁感冒,蓝桥杯,简易AC代码讲解
GeoServer入门学习:04-发布Shapfile地图数据
【转发与重定向(二)】
classfile内容解析
unity报Unable to load the icon: 'CacheServerDisconnected'时的解决办法
2 Scrapy
GeoServer introductory study: 07 - release a larger multi-tiered TIF map data
C语言求积分的近似值
day4——乐优商城项目结构(6个微服务)
【梦想的声音】