斐波那契—如此简单

106 阅读2分钟

这是我参与8月更文挑战的第17天,活动详情查看:8月更文挑战

学算法,数据结构的话动态规划,递归是永远躲不去的坑,今天看几道斐波那契数列数,平时这种问题在课堂上一般都是用递归的方法写的,可是一般的递归又看不懂到底核心是啥情况,这次的算法,我用非递归写斐波那契数列,希望能帮助大家入个门,而且实际上非递归效率更高。 这次选的是剑指Office中的几道题。

斐波那契数列的规律: 0,1,2,3,5,8,13 ... 也就是:

f(0) = 0,f(1) = 1 , f(n) = f(n-1) + f(n-2);

f(0) = 0; f(1) = 1; 写作

if(n <= 0)
    return 0;
if(n == 1)
    return 1;

后续部分写成 Fibonacci(n-2)+Fibonacci(n-1); 递归的方式写成java程序则结果如下:

public class Solution {
    public int Fibonacci(int n) {
        if(n<=0) {
            return 0;
        }
        if(n==1) {
            return 1;
        }
        return Fibonacci(n-2)+Fibonacci(n-1);
    }
}

非递归版

public class Solution {
    public int Fibonacci(int n) {
        if(n<=0) return(0);
        else if(n<=2) return(1);
        int a=1;
        int b=1;
        int sum = 0;
        for(int i=3;i<=n;i++){
            sum = a+b;
            a= b;
            b = sum;
        }
        return sum;
    }
}

讨论一下 递归与非递归的效率问题

一般来说递归效率低是函数调用的开销导致的。 在一个函数调用之前需要做许多工作,比如准备函数内局部变量使用的空间、搞定函数的参数等等,这些事情每次调用函数都需要做,因此会产生额外开销导致递归效率偏低,所以逻辑上开销一致时递归的额外开销会多一些。

第一题当然很简单,同类的还有跳台阶

public class Solution {
    public int JumpFloor(int target) {
        if(target <4)
            return target;
        else {
            int temp1 = 1;
            int temp2 = 2;
            int temp = 3;
            for(int i=3;i<=target ;i++){
                temp = temp1+temp2;
                temp1 = temp2;
                temp2 = temp;
            }
            return temp;
        }
    }
}

以及矩阵覆盖问题

public class Solution {
    public int RectCover(int target) {
        if(target == 1)
            return 1;
        if(target == 2)
            return 2;
        int a=1;
        int b=2;
        int sum = 0;
        for(int i=3;i<=target;i++){
            sum = a+b;
            a=b;
            b=sum;
        }
        return sum;
    }
}