斐波那契数列-牛客(Java)

题目:斐波那契数列

题目描述:大家都知道斐波那契数列,现在要求输入一个正整数 n ,请你输出斐波那契数列的第 n 项。

斐波那契数列是一个满足 fib(x)=1,x = 1,2;fib(x)=fib(x - 1) + fib(x - 2) , x > 2​ 的数列

数据范围:1≤n≤40

要求:空间复杂度 O(1),时间复杂度O(n) ,本题也有时间复杂度O(logn) 的解法

输入描述:一个正整数n

返回值描述:输出一个正整数

示例1:

输入:4

返回值:3

说明:根据斐波那契数列的定义可知,fib(1) = 1, fib(2) = 1,fib(3) = fib(3 - 1) + fib(3 - 2) = 2,fib(4) = fib(4 - 1) + fib(4 - 2) = 3,所以答案为3。

示例2:

输入:1

返回值:1

示例3:

输入:2

返回值:1 

方法一:迭代方法

基本思想:斐波那契数列的特点是,第 n 个数等于第 n - 1 个数和第n - 2 个数的和。那么我们利用这个特点就可以迭代求出第 n 个数的值。

代码实现:

public int Fibonacci(int n) {
        if(n == 0){
            return 0;
        }
        int first = 1;
        int second = 1;
        int third = 1;
        // 如果 n = 0,那么fib(n) = 0,之前就直接返回了
        // 如果 n = 1,那么fib(n) = 1,是 third 的值
        // 如果 n = 2,那么fib(n) = 1,是 third 的值
        // n > 2时,所有的数都满足下面的循环
        while(n > 2){
            third = first + second;
            first = second;
            second = third;
            n--;
        }
        return third;
}

方法二:

基本思想:根据斐波那契数列的特点,我们可以把这个问题看做是一个递归问题,问题规模慢慢变小,但是本质是相同的,这时我们就用分治的思想。

代码实现:

public int Fibonacci(int n){
        if(n == 0){
            return 0;
        }
        if(n < 3){
            return 1;
        }
        // 当n != 0,1,2时,我们就使用递归求解
        return Fibonacci1(n - 1) + Fibonacci1(n-2);
}

虽然方法二的递归方法可以解决这个问题,但是耗费的时间太长,所以我们对这个方法进行改良。

方法二(改良版):

基本思想:我们利用一个 map 来将斐波那契数列的各项保存,这样就不会反复计算已经计算过的数,可以节省时间。

代码实现:

private Map<Integer,Integer> map = new HashMap<>();
public int Fibonacci2(int n){
    if(n == 0){
        return 0;
    }
    if(n <= 2){
        return 1;
    }
    // 前前一个
    int ppre = 0;
    // 判断 map 中是否包含这个值,不包含就添加进去,包含就直接取出来用
    if(map.containsKey(n - 2)){
        ppre = map.get(n - 2);
    }else{
        ppre = Fibonacci2(n - 2);
        map.put(n - 2,ppre);
    }
    // 前一个
    int pre = 0;
    //判断 map 中是否包含这个值,不包含就添加进去,包含就直接取出来用
    if(map.containsKey(n - 1)){
        pre = map.get(n - 1);
    }else{
        pre = Fibonacci2(n - 1);
        map.put(n - 1,pre);
    }
    // 最后就直接返回 前一个数和前前一个数的和
    return pre + ppre;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值