题目:大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。n<=39
解题思路:
首先一下子想到的就是递归。但是这是通过不了的,因为递归占用的空间超过了限定的空间。
递归版本:public int Fibonacci(int n) {
int result=1;
if(n==0){
result=0;
}
if(n==1){
result=1;
}else if(n>=2 && n<=39){
result=Fibonacci(n-2)+Fibonacci(n-1);
}
return result;
}
举个例子:链接:https://www.nowcoder.com/questionTerminal/c6c7742f5ba7442aada113136ddea0c3
n=4,看看程序怎么跑的:
Fibonacci(4) = Fibonacci(3) + Fibonacci(2);
= Fibonacci(2) + Fibonacci(1) + Fibonacci(1) + Fibonacci(0);
= Fibonacci(1) + Fibonacci(0) + Fibonacci(1) + Fibonacci(1) + Fibonacci(0);
由于我们的代码并没有记录Fibonacci(1)和Fibonacci(0)的结果,对于程序来说它每次递归都是未知的,因此光是n=4时f(1)就重复计算了3次之多。
所以,我们应该用迭代代替递归。
然后,我就想到了,把得到的值存到数组中,然后计算的时候取前两个相加就可以了,这样就没有重复多余的运算了。这就用到了动态规划的思想。将大问题化成小问题再求解相加。public int Fibonacci(int n) {
ArrayList<Integer> array=new ArrayList<Integer>();
array.add(0);
array.add(1);
if(n<2){
return array.get(n);
}
else if(n>=2 && n<=39){
for(int i=2;i<=n;i++)
array.add(array.get(i-1) + array.get(i-2));
}
return array.get(n);
}
但是,这个代码运行的空间多出了array.size。相比于前一个递归代码,可以说是用空间换时间。
所以,下面这个代码是参考了牛客网上边一些人的代码,得到的。相比于第二版代码,减少了很多空间,只用了2个变量就解决了。
public int Fibonacci(int n) {
int f1=1,f2=1;
if(n==0) return 0;
if(n==1 || n==2) return 1;
for(int i=3;i<=n;i++){
f1=f1+f2;
f2=f1-f2;
}
return f1;
}