zoukankan      html  css  js  c++  java
  • 第19题:求解斐波拉契数列

    欢迎转载,转载请务必注明出处:http://blog.csdn.net/alading2009/article/details/45456639
    github:https://github.com/frank-cq/MyTest

    第19题(数组、递归):定义Fibonacci数列如下:f(0)=0,f(1)=1,f(n)=f(n-1)+f(n-2)。输入n,用最快的方法求该数列的第n项。

    最容易想到的是递归和迭代的求解方法,但是递归存在重复计算问题,n值越大,重复计算消耗越大。相比而言,迭代是一种较好的方法,时间复杂度O(n)。而效率最高的是矩阵方法,时间复杂度为O(logn),矩阵计算公式如下:

    [fnfn1]=[1110]n1[10]
    此时计算的核心转移到了计算幂矩阵上,采用分治法进行计算,分为幂指数为偶数和奇数两种情况。


    代码

    package test019;
    
    /**
     * Created by cq on 2015/5/13.
     * 第19题(数组、递归):定义Fibonacci数列如下:f(0)=0,f(1)=1,f(n)=f(n-1)+f(n-2)。输入n,用最快的方法求该数列的第n项。
     */
    public class Test019 {
        //一般递归方法,有重复计算
        public static int sumFibRecursion(int n){
            if (n == 0 || n == 1){
                return n;
            }
    
            return sumFibRecursion(n-1) + sumFibRecursion(n-2);
        }
    
        //迭代方法
        public static int sumFibIteration(int n){
            if (n < 0){
                System.out.println("n不应小于0!");
                return -1;
            }
    
            int fibN = n, fibN_1 = 1, fibN_2 = 0;
            for (int i=2; i<=n; i++){
                // f(n) = f(n-1) + f(n-2)
                fibN = fibN_1 + fibN_2;
                fibN_2 = fibN_1;
                fibN_1 = fibN;
            }
    
            return fibN;
    
    //        int[] arr = {0,1};
    //        for (int i=2; i<=n; i++){
    //            if (i&1 == 0){
    //                arr[0] = arr[0] + arr[1];
    //            }
    //            else {
    //                arr[1] = arr[0] + arr[1];
    //            }
    //        }
    //        return arr[n&2];
        }
    
        //矩阵递归方法,无重复计算,根据计算公式:(f(n),f(n-1))^T = A^(n-1) * (1,0)^T
        public static int sumFibMatrix(int n){
            if (n < 0){
                return -1; 
            }
            int[] matrix = {1,1,1,0};
            matrixPower(matrix,n-1);
            return matrix[0];
        }
        //分治法求矩阵的n次幂(效率就在这儿)
        public static void matrixPower(int[] matrix, int n){
            if (matrix == null || matrix.length != 4 || n <0){
                return;
            }
            if (n == 0){
                matrix[0] = matrix[1] = matrix[2] = matrix[3] = 1;
                return;
            }
            else if (n == 1){
                matrix[0] = matrix[1] = matrix[2] = 1;
                matrix[3] = 0;
                return;
            }
            //偶次幂,A^n = A^(n/2) * A^(n/2)
            if ((n&1) == 0){
                matrixPower(matrix,n/2);
                calculateMatrix(matrix,matrix,matrix);
            }
            //奇次幂,A^n = A^((n-1)/2) * A^((n-1)/2) * A
            else {
                matrixPower(matrix,(n-1)/2);
                calculateMatrix(matrix,matrix,matrix);
                calculateMatrix(matrix,new int[]{1,1,1,0},matrix);
            }
    
        }
        //二阶矩阵相乘(将二阶矩阵映射到一维数组上)
        public static void calculateMatrix(int[] matrixA, int[] matrixB, int[] matrix){
            if (matrixA == null || matrixA.length != 4 ||
                    matrixB == null || matrixB.length != 4){
                return;
            }
            int value00 = matrixA[0]*matrixB[0] + matrixA[1]*matrixB[2];
            int value01 = matrixA[0]*matrixB[1] + matrixA[1]*matrixB[3];
            int value10 = matrixA[2]*matrixB[0] + matrixA[3]*matrixB[2];
            int value11 = matrixA[2]*matrixB[1] + matrixA[3]*matrixB[3];
            matrix[0] = value00;
            matrix[1] = value01;
            matrix[2] = value10;
            matrix[3] = value11;
        }
    
        public static void main(String[] args){
    
            System.out.println("使用递归求解斐波拉契数列结果:"+sumFibRecursion(10));
    
            System.out.println("使用迭代求解斐波拉契数列结果:"+sumFibIteration(10));
    
            System.out.println("使用矩阵求解斐波拉契数列结果:"+sumFibMatrix(10));
        }
    }
    




    执行结果

    Connected to the target VM, address: '127.0.0.1:19344', transport: 'socket'
    Disconnected from the target VM, address: '127.0.0.1:19344', transport: 'socket'
    使用递归求解斐波拉契数列结果:55
    使用迭代求解斐波拉契数列结果:55
    使用矩阵求解斐波拉契数列结果:55
    
    Process finished with exit code 0



    ps:最近实验室的项目做得真是欲仙欲死,论文也写得蛋疼,好久没做题了。

  • 相关阅读:
    公司的OA系统基础框架系统(光标办公平台)
    通用权限控制系统--系统设计
    聘.Net软件工程师(昆明)
    对AgileFramework的思考
    iTextSharp.text.Rectangle 使用方法说明
    Castle Aspect# 难倒只支持一个拦截器?
    聘云南昆明地区的.Net工程师
    招聘云南软件销售人员
    给vncviewer 添加调用函数 GIS
    分享一个c++ 加密算法 ,在百度贴吧找的,比较好玩 GIS
  • 原文地址:https://www.cnblogs.com/read-the-spring-and-autumn-annals-in-night/p/12041977.html
Copyright © 2011-2022 走看看