7.斐波那契数列(黄金分割数列、兔子数列):f(1)=1,f(2)=1,f(n) = f(n-1) + f(n-2)(n>3)
1.O(n)时间复杂度用迭代;
2.O(logn)用矩阵相乘 切记不要用递归)
这题可以说是迭代VS递归
递归:
if(n<=1) return n;
else return Fibonacci(n-1)+Fibonacci(n-2);
由于我们的代码并没有记录Fibonacci(1)和Fibonacci(0)的结果,对于程序来说它每次递归都是未知的,因此光是n=4时f(1)就重复计算了3次之多。
递归本质上是栈,(测试用例里肯定准备着一个超大的n来让Stack Overflow)可能导致栈溢出,为什么会溢出?因为重复计算。
递归的优点在于便于理解和编码,而重复计算的关键原因在于代码里直接就“递”进去然后等着“归”了,所以避免重复的关键在于对子问题是否已经得出解的判断。
利用递归可以解决很多问题:如背包问题,汉诺塔问题,…等.
迭代
迭代利用变量的原值推算出变量的一个新值.如果递归是自己调用自己的话,迭代就是A不停的调用B.
这道题最好对比跳台阶对比学习:
public class Solution {
public int Fibonacci(int n) {
int fn1=1;
int fn2=1;
int fn=0;
if(n<=0) return 0;
if(n==1||n==2){
return 1;
}
for(int i=3;i<=n;i++){
fn=fn1+fn2;
fn1=fn2;
fn2=fn;
}
return fn;
}
}
二刷的问题:很愚蠢的使用了递归的方式,而使用迭代的方式这题耗时更少主要是递归的方式每次都会重新计算之前计算过的值。
fn=fn-1+fn-2;
fn-1=fn-2;
fn-2=fn;