题目描述:
大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。
n<=39
斐波那契数列:f(n) = f( n - 1) + f(n - 2) f(1)= 1 f(2)=1
思路1:斐波那契数列是典型的迭代递归数列,最简单的方式是按f(n) = f( n - 1) + f(n - 2)的规则进行简单的迭代实现
代码1:
public class Solution {
public static void main(String[] args) {
// TODO Auto-generated method stub
Solution solution = new Solution();
System.out.println(solution.Fibonacci(39));
}
public int Fibonacci(int n) {
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
}
if (n == 2) {
return 1;
}
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
}
思路2:由于Java中每次迭代都会耗费较多的资源,因此可以通过使用循环替代迭代的方式来实现
public class Solution {
public static void main(String[] args) {
// TODO Auto-generated method stub
Solution solution = new Solution();
System.out.println(solution.Fibonacci(39));
}
public int Fibonacci(int n) {
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
}
if (n == 2) {
return 1;
}
int r1 = 1;
int r2 = 1;
int x;
while(n > 2){
x = r1;
r1 = r2;
r2 = x + r1;
--n;
}
return r2;
}
}
思路3:将f(n)展开得到f(n) = f(n - 1) + f(n - 2) = 2f(n - 2) + f(n - 3) = 3f(n - 3) + 2f(n - 4) = 5f(n - 4) + 3f(n - 5) = 8f(n - 5) + 5f(n - 6) ... ... 同时已知部分斐波那契数列为1,1,2,3,5,8,13... ... 结合两者可以得到f(3) = f(2) ^2 + f(1)^2, f(5) = f(3)^2 + f(2)^2, f(7) = f(4)^2 + f(3)^2 ... ... 总结可知f(2n - 1) = f(n)^2 + f(n-1)^2。因此可以对其中n为奇数的部分进行优化计算。通过迭代的方式得到的代码如下:
package com.sam.algorithm;
public class Solution {
public static void main(String[] args) {
// TODO Auto-generated method stub
Solution solution = new Solution();
System.out.println(solution.Fibonacci(39));
}
public int Fibonacci(int n) {
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
}
if (n == 2) {
return 1;
}
if (n % 2 == 1) {
int x = Fibonacci((n + 1) / 2);
int y = Fibonacci((n) / 2);
return x * x + y * y ;
}else {
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
}
}
通过多次运算发现在本人的机器上当n=39时方法二和方法三的速率均为方法一的1000倍左右。