斐波那契数列o(logn)求法
斐波那契数列
如果从第0个位置开始
下标;0 1 2 3 4 5 6 7 8 …
值: 1 1 2 3 5 8 13 21 34…
斐波那契数列推导(当n>=1)
F(2n)=F(2n-1)+F(2n-2) = F(2n-2)+F(2n-3)+F(2n-2)
=(1+1)F(2n-2)+F(2n-3) =F(2)F(2n-2)+f(1)F(2n-3)=2{F(2n-3)+F(2n-4)}+F(2n-3)
=(2+1)F(2n-3)+2F(2n-4) =F(3)F(2n-3)+f(2)F(2n-4)=3{F(2n-4)+F(2n-5)}+2F(2n-4)
=(3+2)F(2n-4)+3F(2n-5)=F(4)F(2n-4)+f(3)F(2n-5)=5{F(2n-5)+F(2n-6)}+3F(2n-5)
=(3+5)F(2n-5)+5F(2n-6)=F(5)F(2n-5)+f(4)F(2n-6)=8{F(2n-6)+F(2n-7)}+5F(2n-6)
=F(6)F(2n-6)+f(5)F(2n-7)
…
=F(n)F(2n-n)+F(n-1)F(2n-(n+1))=F(n)F(n)+F(n-1)F(n-1)
验算一下:
F(2)=F(1)F(1)+F(0)F(0)=1+1=2
F(4)=F(2)F(2)+F(1)F(1)=5
F(8)=F(4)F(4)+F(3)F(3)=25+9=34
接下来同理,自己推(此时n>=2)
F(2n-1)=F(n-1)F(n)+F(n-2)F(n-1)
验算一下:
F(3)=F(1)F(2)+F(0)F(1)=2+1=3
F(5)=F(2)F(3)+F(1)F(2)=6+2=8
F(7)=F(3)F(4)+F(2)F(3)=15+6=21
代码(o(n)递归)
(不推荐用这个,太慢了)
public static int get_Fibonacci(int n){if(n==0) return 1;if(n==1) return 1;return get_Fibonacci(n-1)+get_Fibonacci(n-2);
}
代码(o(n)迭代)
其实就是空间换时间
public static int get_Fibonacci(int n){if(n<2) return 1;int[] Fibonacci=new int[n+1];Fibonacci[0]=1;Fibonacci[1]=1;if(n<2) return Fibonacci[n];for(int i=2;i<=n;i++){Fibonacci[i]=Fibonacci[i-1]+Fibonacci[i-2];}return Fibonacci[n];
}
代码(o(logn)递归)
别这样写,加个记忆化吧。
public static int get_Fibonacci(int n){if(n==0) return 1;if(n==1) return 1;if(n%2==0) return get_Fibonacci(n/2)*get_Fibonacci(n/2)+get_Fibonacci(n/2-1)*get_Fibonacci(n/2-1);else return get_Fibonacci(n/2)*get_Fibonacci(n/2+1)+get_Fibonacci(n/2-1)*get_Fibonacci(n/2);
}
代码(o(logn)递归-记忆化)`
public static final int MAX_NUM=100000;public static int Fibonacci[]=new int[MAX_NUM];public static int get_Fibonacci(int n){if(n==0) return Fibonacci[0]=1;if(n==1) return Fibonacci[1]=1;if(Fibonacci[n]>0) return Fibonacci[n];if(n%2==0) return Fibonacci[n]=(get_Fibonacci(n/2)*get_Fibonacci(n/2)+get_Fibonacci(n/2-1)*get_Fibonacci(n/2-1));else return Fibonacci[n]=(get_Fibonacci(n/2)*get_Fibonacci(n/2+1)+get_Fibonacci(n/2-1)*get_Fibonacci(n/2));
}
``