斐波那契数列

什么是斐波那契数列

斐波那契数列指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2)

求数列中第n个数的值

本文总共总结了四种方法,欢迎大家补充。

方法一

  1. 首先最简单的就是直接法,利用迭代依次进行计算。
class Solution {
public:
    int Fibonacci(int n) 
    {
    	if(n < 0)               // 输入不符合要求
    	{
    		return -1;
    	}
    	
        if(n == 0 || n == 1)
        {    
        	return n;
        }
        
        int first = 0;
        int second = 1;
        int third = 1;
        
        while(n-- > 2)          // 循环n - 3次
        {
            first = second;     // 先后移,后相加
            second = third;
            third = first + second;
        }
        
        return third;
    }
};

方法二

  1. 第二种方法和第一种同样是利用了迭代的方法,不过只使用了两个临时变量。
class Solution
{
public:
    int Fibonacci(int n) 
    {
        if(n < 0)
        {
            return -1;
        }
        
        if(n == 0 || n == 1)
        {
            return n;
        }
        
        int first = 0;
        int second = 1;
        
        while(n-- > 1)           // 循环n - 2 次
        {
            second = first + second;  // second表示第三个值
            first = second - first;   // first表示第二个值
        }
        
        return j;
    }
};

方法三

  1. 利用递归进行计算,因为根据定义在n > 2时,f(n) = f(n - 1) + f(n - 2),要想求得f(n)的值,就必须先求得f(n - 1)和f(n - 2)的值,以此类推,最终会在0或1处结束递归。
class Solution {
public:
    int Fibonacci(int n) 
    {
    	if(n < 0)
    	{
    		return -1;
    	}
    	
        if(0 == n || 1 == n) // 递归出口
        {
            return n;
        }
        
        // 递归计算之前每一个的值并返回
        return Fibonacci(n - 2) + Fibonacci(n - 1); 
    }
};

方法四

  1. (重点) 利用递归的方法解决问题看上去代码很简洁明了,但是当n的值较大时,它的效率明显变得很低。
    这里一是因为递归层数过多,堆栈层数也会随之增多,甚至如果太大的话会致使程序中断;二是因为这个方法在计算的时候有很多无效的重复的计算,比如说如果要计算f(4),那么就要先计算f(3)和f(2),那么在计算f(3)的时候,就必须要先计算f(2)和f(1),这里就可以发现,f(2)被重复计算了,每次需要用到它的时候都会调用一次Fibonacci(2),但实际上这个值我们之前就已经计算过了,同理如果n的值足够大,那么这种重复的计算所产生的内存消耗是不可估量的
    解决方法:剪枝,可以将之前计算过的值都保存下来,之后需要使用的话可以直接查找,如果没有的话再去进行计算并保存。这里我们使用哈希表来存储。
class Solution {
private:
    unordered_map<int, int> filter;  // C++中unordered_map内部实现了哈希表
    
public:
    int Fibonacci(int n) 
    {
    	if(n < 0)
    	{
    		return -1;
    	}
    	
        if(0 == n || 1 == n)
        {
            return n;
        }
        
        int pre = 0;   //n - 1位置
        int ppre = 0;  //n - 2位置
        
        // 利用find()函数在filter中查找是否已经存在了key == n - 1的数据
        if(filter.find(n - 1) == filter.end()) // 没有
        {
            pre = Fibonacci(n - 1);        // 递归
            filter.insert({n - 1, pre});   // 将求得的结果插入到filter
        }
        else // 之前已经计算过f(n - 1)的值
        {
            pre = filter[n - 1];
        }
        
        if(filter.find(n - 2) == filter.end())
        {
            ppre = Fibonacci(n - 2);
            filter.insert({n - 2, ppre}); 
        }
        else
        {
            ppre = filter[n - 2];    
        }
        
        return ppre + pre;  // 相加返回
    }
};

结束

斐波那契数列是一个比较基础的问题,同时也是笔试面试中比较常见的问题,本文主要是学习一下常见的几种方法及剪枝的思想,希望这篇博客能够对你有所帮助。
第一次用博客的方式来记录学习,通过文字的方式来将算法的思想描述出来,确实跟自己看不太一样哈。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值