1. 问题描述
写一个函数,输入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
2. 解题思路
递归一:
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)为例来看下
我们看到上面相同颜色的都是重复计算,当n越大,重复的越多,所以我们可以使用一个map把计算过的值存起来,每次计算的时候先看map中有没有,如果有就表示计算过,直接从map中取,如果没有就先计算,计算完之后再把结果存到map中。
递归三:
class Solution {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);}else{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 result = (first+second)%constant;map.put(n,result);return result;}}
}