递归算法之阅读挑战赛

14天阅读挑战赛
努力是为了不平庸~
算法学习有些时候是枯燥的,这一次,让我们先人一步,趣学算法!欢迎记录下那些努力的时刻(算法学习知识点/算法题解/遇到的算法bug/等等),在分享的同时加深对于算法的理解,同时吸收他人的奇思妙想,一起见证技术er的成长~

       ‍❄️                     ‍❄️      

 ♔博主昵称:�欢快↑㎡

博客主页:�欢快↑㎡的博客_CSDN博客-学习注意点杂记,BUG集,安装教程领域博主

感谢点赞评论收藏

⚇很方便的在线编辑器:Lightly

相信吧!我们很优秀,还可以更加优秀,加油!让我们一起在写作中记录巩固学习吧!


目录

算法知识点

算法题目来源

算法题目描述

做题思路


算法知识点

递归算法

时间复杂度

空间复杂度

迭代法

算法题目来源

关于兔子繁殖的问题·相信我们之前就在数学课本上遇到过,今天我们一起学习趣学算法中是怎么用程序解决该问题的,为了效率性能又做了哪些优化

算法题目描述

假设第1个月有1对初生的兔子,第2个月进入成熟期,第3个月开始生育兔子,而1对成熟的兔子每月会生1对兔子,兔子永不死去.....,那么,由1对初生的兔子开始,12个月后会有多少对兔子呢?


兔子数列即斐波那契数列,它的发明者是意大利数学家莱奥纳尔多斐波那契(Leonardo Fibonacci, 1170一1250) 。

做题思路

问题分析

如图所示

第1个月,小兔子①没有繁殖能力,所以还是1对。
第2个月,小兔子①进入成熟期,仍然是1对。
第3个月,兔子①生了1对小兔子②,于是这个月共有2------(1+1=2) 对兔子。
第4个月,兔子①又生了1对小兔子③,因此共有3------(1+2=3) 对兔子。
第5个月,兔子①又生了1对小兔子④,而在第3个月出生的兔子②也生下了1对小兔子⑤,因此共有5------(2+3=5)对兔子。

递归算法之阅读挑战赛_第1张图片

这个数列从第3个月开始,当月的兔子数=上月兔子数+当月新生兔子数,而当月新生兔子数正好等于上月的兔子数。因此,前面相邻两项之和便构成后一项,换言之:当月的兔子数=当月兔子数+上月的兔子数

可以用如下表达式表达

递归算法之阅读挑战赛_第2张图片

算法设计

可以设计一个递归算法(调用其本身)

int Fib1(int n) {
   if(n == 1) || (n == 2);
   return 1;
   return Fib(n-1) + Fib(n-2);
}

其时间复杂度

T(n)=1 n=1||n=2

T(n)=T(n-1)+T(n-2)+1;

T(n)>F(n),但是如图很容易看出递归算法是指数级的,性能会很差

递归算法之阅读挑战赛_第3张图片

 算法改进

利用数组,让其只用遍历n-2次,可以看成是F(n)

int Fib2(int n){
int *F=new int[n+1];//定义一 个长度为n+1的数组,空间尚未使用
F[1]=1;
F[2]=1;
for(int i=3;i<=n;i++) { //遍历,为下标3-n的元素赋值
F[i]=F[i-1]+F[i-2];
}
return F[n]; //返回n下标出的元素就是第n个月的兔子对数

迭代法

我们注意到数组的size是n(空间复杂度是O(n))比较占空间,小案列中可能感觉没什么但是如果n非常大,或者存储数据很大,就影响比较大了,所以我们可以借助一个中间变量,减少空间占据

int Fib3(int n) { 
if(n==1||n==2) {
return 1;
}
int s1=1; //用s1和s2记录前面的两项
int s2=1;
for(int i=3;i<=n;i++){
int tmp=s1+s2;
s1=s2;
s2=tmp;
}
return s2;

这样空间复杂度便可以降到O(1)

你可能感兴趣的:(算法,数据结构)