剑指 Offer 10- I. 斐波那契数列
思路
递归写法
由题目中给出的斐波那契的递推公式f(n) = f(n - 1) + f(n - 2)可以我们可以直接使用递归来计算每一个f(n)的值,最后回溯的时候使得f(n) = f(n - 2) + f(n - 1)
class Solution {
final int mod = 1000000007;
public int fib(int n) {
if(n <= 1) return n;
return (fib(n - 1) % mod + fib(n - 2) % mod) % mod;
}
}
上述的代码应该是最容易想到的代码,但是再上述的代码中进行了大量的重复性的计算,例如f(10)要计算f(9)和f(8),而f(9)又要重复的计算f(8)了,这样就会造成大量的重复计算,使得我们的程序变得极其的慢。
解决方案:使用记忆化的递归
使用一个数组记录我们已经计算哪一项并将结果存在数组中,如果下一次再次碰到这个项的时候,直接返回即可,不需要重复的递归求解
class Solution {
final int mod = 1000000007;
int[] st = new int[101];
{
st[0] = 0; st[1] = 1;
}
public int fib(int n) {
if(n <= 1) return n;
if(st[n] != 0) return st[n];
//回溯之后做加法,表示这个值已经计算完成了
return st[n] = (fib(n - 1) % mod + fib(n - 2) % mod) % mod;
}
}
迭代
直接按照斐波那契的公式推过去就行了
class Solution {
final int mod = 1000000007;
public int fib(int n) {
if(n <= 1) return n;
int a = 0, b = 1, sum = 0;
for(int i = 0; i < n - 1; ++ i){
sum = (a % mod + b % mod) % mod;
a = b; b = sum;
}
return sum;
}
}
也是可以开一个数组dp,使得dp[n] = dp[n - 1] + dp[n - 2],最后直接返回dp[n]就可以了。
如有错误,欢迎指正!