Fibonacci 解题报告

来源:互联网 发布:u深度安装linux 编辑:程序博客网 时间:2024/05/17 06:18

Fibonacci

Description

Find the Nth number in Fibonacci sequence.

A Fibonacci sequence is defined as follow:

The first two numbers are 0 and 1.The i th number is the sum of i-1 th number and i-2 th number.

The first ten numbers in Fibonacci sequence is:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ...

Notice
The Nth fibonacci number won’t exceed the max value of signed 32-bit integer in the test cases.

Example

If n = 15, you should return:

Given 1, return 0Given 2, return 1Given 10, return 34

实现思路

Fibonacci 方程满足f(i) = f(i-1) + f(i-2)
这里给出两种实现思路,一种是基于迭代,另一种则基于递归,基于递归又分为直接递归和尾递归。

实现方法1:基于迭代

注意好边界问题,确定返回pre而非cur,每次迭代需要使pre和cur前进一步。

/**     * @param n: an integer     * @return an integer f(n)     */    public int fibonacci(int n) {        int pre = 0,cur = 1,tmp;        for(int i = 1 ; i < n; i ++ ){            cur += pre;            pre = cur - pre;         }        return pre;    }

实现方法2:基于非尾递归

public int fibonacci(int n) {    if(n <= 1){        return 0;    }else if(n == 2){        return 1;    }else{        return fibonacci(n-1) + fibonacci(n-2);    }}

使用这个方法会超时,原因是每次计算fibonacci(n-1)或fibonacci(n-2)都需要重新计算一遍,类似过程如下所示:

Fib(6) = Fib(5) + Fib(4);    = Fib(4) + Fib(3) + Fib(3) + Fib(2);    = Fib(3) + Fib(2) + Fib(2) + Fib(1) + Fib(2) + Fib(1) + Fib(2);    = Fib(2) + Fib(1) + Fib(2) + Fib(2) + Fib(1) + Fib(2) + Fib(1) + Fib(2);

如果要对此进行改进,我们可以缓存中间结果,然后每次从缓存结果中读取即可。
下面我们看基于尾递归的实现

实现方法3: 基于尾递归

基于尾递归在LintCode上是能通过的,在给出代码前,先介绍尾递归:
顾名思义,尾递归就是从最后开始计算, 每递归一次就算出相应的结果, 也就是说, 函数调用出现在调用者函数的尾部, 因为是尾部, 所以根本没有必要去保存任何局部变量. 直接让被调用的函数返回时越过调用者, 返回到调用者的调用者去。尾递归就是把当前的运算结果(或路径)放在参数里传给下层函数,深层函数所面对的不是越来越简单的问题,而是越来越复杂的问题,因为参数里带有前面若干步的运算路径。
下面是具体实现的代码:

public int fibonacci(int n){    if (n == 1){        return 0;    }else if(n == 2)        return 1;    else        return Tail(n, 0, 1, 3);}private int Tail(int n, int b1, int b2, int begin){    if (n == begin){        return b1 + b2;    }else{        return Tail(n, b2, b1 + b2, begin + 1);    }}

为了加深对代码的理解,我们用一个过程来模拟:

fibonacci(7) = Tail(7, 0, 1, 3)     = Tail(7, 1, 2, 4)     = Tail(7, 2, 3, 5)     = Tail(7, 3, 5, 6)     = 8

很容易看到,整个尾递归过程,只有不断往深,但却不用不必要往回(进行相加),故对于支持尾递归的语言,其编译器会进行优化。

0 0