斐波那契数列(面试算法)

题目描述:

大家都知道斐波那契数列,现在要求输入一个整数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倍左右。

你可能感兴趣的:(java,算法)