剑指Offer的学习笔记(C#篇)-- 斐波那契数列

题目:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。

一 . 理解概念

        斐波那契数列概念:斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”(来自百度百科)。具体可由以下公式表示:

二.C#代码如何实现

        由上述公式可知,斐波那契数列存在两个特殊值,即当n=0和n=1时,因此,可将n等于0与1时提出来作单独处理,而剩下的部分再作单独处理,基于这种想法,实现该目标可使用两种方法:

方法1:递归法。

        斐波那契数列是递归法最典型的一种体现,但又存在着很多的不足。

        其中,递归的实现是通过调用函数本身,函数调用的时候,每次调用时要做地址保存,参数传递等,这是通过一个递归工作栈实现的。具体是每次调用函数本身要保存的内容包括:局部变量、形参、调用函数地址、返回值。那么,如果递归调用 N 次,就要分配 N*局部变量、N*形参、N*调用函数地址、N*返回值,这势必是影响效率的,该题目中,用递归方法计算的时间复杂度是以n的指数的方式递增的,此段来自Edison Zhou的博文。

        如下代码是使用递归实现的斐波那契数列(该题目中可以看出,若你>1,计算f(n)需要不断重新的调用Fibonacci函数):

class Solution{
     public int Fibonacci(int n)
    {
        //当n小于等于0时,返回0
        if (n <= 0)
        {
            return 0;
        }
        //当n等于1时,返回1
        if (n == 1)
        {
            return 1;
        }
        //否则,返回前两个数之和
        else
       {
             return Fibonacci(n - 1) + Fibonacci(n - 2);  
        } 
    }
}

 

        很显然,递归虽然可以实现斐波那契数列,但却存在着一定的问题。

 方法二 : 循环法。

        由于递归存在着效率低问题,为解决该问题,引入循环的方法避免了递归法重复计算的弊端,从而运算的时间复杂度变为是O(n)。

        具体实现代码如下:

class Solution
{
    public int Fibonacci(int n)
    {
        // write code here
        int x = 0;
        int y = 1;
        int result = 0;
        if (n == 0)
        {
            return 0;
        }
        if (n == 1)
        {
            return 1;
        }
        else
        {
            for (int i=2;i<=n;i++)
        {
            result = x + y;
            x = y;
            y = result;
        }
            return result;
        }
    }
}

        上述代码在实现上与递归法大同小异,不同点在于不需要重复的调用函数,个人感觉理解起来更加容易一点。

 

posted @ 2019-05-18 14:20  WeiMLing  阅读(306)  评论(0编辑  收藏  举报