[PTA]7-26 函数-斐波那契数列(递归函数运行超时的优化方案)

文章讨论了如何解决斐波那契数列计算中的递归方法缺陷,介绍了动态规划法和迭代法,强调了在实际编程中应追求算法效率的重要性。
摘要由CSDN通过智能技术生成

题源:PTA

题目描述:7-26 函数-斐波那契数列

分数 20      作者 韩玫瑰      单位 济南大学

斐波那契数列(Fibonacci Sequence),又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、……。在数学上,斐波纳契数列以递推的方法定义为:F(1)=1,F(2)=1,F(n)=F(n-1)+F(n-2)(n≥2,n∈N)。计算斐波那契数列第n项的值。

输入格式:输入一个大于等于1,小于等于60的整数n。

输出格式:输出第n项的数列值,数列值为double类型,不输出小数位数。

输入样例:

20

输出样例:

6765

输入样例:

1

输出样例:

1

代码长度限制        16 KB

时间限制              400 ms

内存限制              64 MB

这道题首先会想到使用递归函数的方法,递归一法确实可行,但递归一法也存在一些缺陷(这点我会在稍后提出),使用递归函数代码如下:

#include<stdio.h>
double fib(double n)
{
    double f;
    if(n==1||n==2)
    {f=1;}
    else
    {f=fib(n-1)+fib(n-2);}
    return f;
}
int main()
{
    double n,f;
    scanf("%lf",&n);
    f=fib(n);
    printf("%.lf",f);
    return 0;
}

运行代码后,我们发现了一些问题,即在输入数据较小时使用递归函数一法确实可行,但是当数据稍大时(在PTA上输入大于等于41的数据)就会出现运行超时的问题,所以递归函数一法并不是该题的最优解

所以我们引进另外几种方法:

①动态规划法:即将每一个计算出来的数据保存在数组中,需要时直接总数组中取出即可,能避免重复计算。其中会使用到一个for循环,所以时间复杂度为Ο(n),使用到一个长度为n的数组,所以空间复杂度也为Ο(n)。该方法代码如下:

#include<stdio.h>
int main()
{
    int n;
    scanf("%d",&n);
    double fib[61];
    fib[0]=1;
    fib[1]=0;
    int i;
    for(i=3;i<=n;i++)
    {
        fib[i]=fib[i-1]+[i+1];
    }
    printf("%.lf",fib[n]);
}

运行后我们发现超时问题被有效解决了;但我们发现尽管上述算法已经很高效了,但还是有一个问题,即整个数组中,每次计算时都只需要最新的3个值,前面的值计算完后就不再需要了。所以我们还可以改进,这便是我们的第二个算法。

②迭代法:即通过3个变量来存储数据,时间复杂度仍然为O(n),而空间复杂度为常量级别3,即空间复杂度为0,代码如下:

#include<stdio.h>
int main()
{
    double n,first=1,second=1,third;
    scanf("%lf",&n);
    if(n==1||n==2)
    {third=1;}
    int i;
    for(i=3;i<=n;i++)
    {
        third=second+first;
        first=second;
        second=third;
    }
    printf("%.lf",third);
    return 0;
}

由一道题引发的思考:斐波那契数列是递归函数的经典运用之一,但通过这道题我们发现递归算法尽管非常实用,但它存在很大的缺陷,即时间复杂度和空间复杂度都很高,所以在使用递归时,要使用一些手段去优化它,就例如上述的动态规划法和迭代法等,另外算法也不是说越简短越好,我们更应该追求的应该是效率,一个好的算法应该要兼顾效率和简洁,需要不断地去思考和打磨

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值