剑指offer第二版-10.斐波那契数列

本系列导航:剑指offer(第二版)java实现导航帖

面试题10:斐波那契数列

题目要求:
求斐波那契数列的第n项的值。f(0)=0, f(1)=1, f(n)=f(n-1)+f(n-2) n>1

解法比较:
解法3,4将问题数学化,借助数学工具的推导,从根本上减低时间复杂度。

解法 解法介绍 时间复杂度 空间复杂度
解法1 依定义递归求解 o(n^2) o(1)
解法2 从0开始迭代求解 o(n) o(1)
解法3 借助等比数列公式 o(logn) o(1)
解法4 借助通项公式 o(1) o(1)

代码:

package chapter2;

/**
 * Created by ryder on 2017/6/21.
 * 斐波那契数列
 * f(0)=0,f(1)=1,f(n)=f(n-1)+f(n-2) n>1
 */
public class P74_Fibonacci {

    // 依据原始概念的递归解法,时间复杂度o(n^2)
    public static int fibonacci1(int n){
        if(n<=0)
            return 0;
        if(n==1)
            return 1;
        return fibonacci1(n-1)+fibonacci1(n-2);
    }

    // 当前状态只与前两个状态有关。存储前两个值,计算后一个,迭代进行。时间复杂度o(n)
    public static int fibonacci2(int n){
        if(n<=0)
            return 0;
        if(n==1)
            return 1;
        int temp1 =0,temp2=1;
        int result = temp1 + temp2,i=3;
        while(i<=n){
            //也可用一个队列来完成下面三行的操作
            temp1 = temp2;
            temp2 = result;
            result = temp1+temp2;
            i++;
        }
        return result;
    }

    // 借助如下数学公式解决问题。矩阵乘法部分,可用递归解决,时间复杂度o(logn)
    // [ f(n)  f(n-1) ] = [ 1  1 ] ^ n-1   (当n>2)
    // [f(n-1) f(n-2) ]   [ 1  0 ]
    // 证明:
    // [ f(n)  f(n-1) ] = [ f(n-1)+f(n-2)  f(n-1)] = [ f(n-1)  f(n-2)] * [1 1]
    // [f(n-1) f(n-2) ]   [ f(n-2)+f(n-3)  f(n-2)]   [ f(n-2)  f(n-3)]   [1 0]
    // 得到如上递推式,所以
    // [ f(n)  f(n-1) ] = [ f(2)  f(1)] * [1 1]^n-2 = [1 1]^n-1
    // [f(n-1) f(n-2) ]   [ f(1)  f(0)]   [1 0]       [1 0]
    public static int fibonacci3(int n){
        int[][] start = {{1,1},{1,0}};
        return matrixPow(start,n-1)[0][0];
    }
    public static int[][] matrixPow(int[][] start,int n){
         if((n&1)==0){
             int[][] temp = matrixPow(start,n>>1);
             return matrixMultiply(temp,temp);
         }
         else if(n==1){
             return start;
         }
         else{
             return matrixMultiply(start,matrixPow(start,n-1));
         }
    }
    public static int[][] matrixMultiply(int[][] x,int[][] y){
        int[][] result = new int[x.length][y[0].length];
        for(int i=0;i

运行结果

233
233
233
233

你可能感兴趣的:(剑指offer第二版-10.斐波那契数列)