c语言斐波那契数列_剑指 Offer 10. 斐波那契数列-I(简单)

写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项。斐波那契数列的定义如下:

F(0) = 0,   F(1) = 1
F(N) = F(N - 1) + F(N - 2), 其中 N > 1.

斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。

答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

示例 1:

输入:n = 2
输出:1

示例 2:

输入:n = 5
输出:5

提示:

  • 0 <= n <= 100

答案:

1,递归解决

之前讲356,青蛙跳台阶相关问题的时候提到过斐波那契数列,代码比较简单

public int fib(int n) {
    if (n < 2)
        return n;
    return fib(n - 1) + fib(n - 2);
}

当n很大的时候可能会出现数字溢出,所以我们需要用结果对1000000007求余,但实际上可能还没有执行到最后一步就已经溢出了,所以我们需要对每一步的计算都要对1000000007求余,代码如下

int constant = 1000000007;

public int fib(int n) {
    if (n < 2)
        return n;
    int first = fib(n - 1) % constant;
    int second = fib(n - 2) % constant;
    return (first + second) % constant;
}

之前讲过斐波那契数列递归的时候会造成大量的重复计算,比如就计算fib(6)为例来看下

1b07aa328057c0d54e98f7d0d2e1488a.png

我们看到上面相同颜色的都是重复计算,当n越大,重复的越多,所以我们可以使用一个map把计算过的值存起来,每次计算的时候先看map中有没有,如果有就表示计算过,直接从map中取,如果没有就先计算,计算完之后再把结果存到map中。

int constant = 1000000007;

public int fib(int n) {
    return fib(n, new HashMap());
}

public int fib(int n, Map<Integer, Integer> map) {
    if (n < 2)
        return n;
    if (map.containsKey(n))
        return map.get(n);
    int first = fib(n - 1, map) % constant;
    map.put(n - 1, first);
    int second = fib(n - 2, map) % constant;
    map.put(n - 2, second);
    int res = (first + second) % constant;
    map.put(n, res);
    return res;
}

看一下运行结果

9691c70d91b4d42114e8dbc8288ce448.png

2,非递归解法

我们还可以把斐波那契递归改为非递归,代码很简单,可以看下

public int fib(int n) {
    int constant = 1000000007;
    int first = 0;
    int second = 1;
    while (n-- > 0) {
        int temp = first + second;
        first = second % constant;
        second = temp % constant;
    }
    return first;
}

看一下运行结果

3099d5d6ecfbdad9ad061bfb0e8be569.png

5118d74ea3d655d6d54f24446f650703.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值