算法与数据结构面试题(17)-求Fibonacci数的和

来源:互联网 发布:淘宝投诉卖家好评返现 编辑:程序博客网 时间:2024/05/17 05:17

题目


题目:定义Fibonacci 数列如下:/ 0 n=0f(n)= 1 n=1\ f(n-1)+f(n-2) n=28输入n,用最快的方法求该数列的第n 项。要求时间复杂度为Olog(n)


解题思路


前人文章:http://zhedahht.blog.163.com/blog/static/25411174200722991933440/


问题转化为求下面的公式




这个2×2的矩阵用一个矩阵对象表示。里面有4个属性,分别表示f(n),f(n-1),f(n-1),f(n-2),求f(n)就是得到第一个属性的值。


求矩阵的公式,采用分治法。




这样就得到了矩阵的{1,1,1,0}的n-1次方的值。


下面是2个矩阵相乘的公式:




代码


public class Problem19 {    // 2×2的矩阵    class Matrix2X2 {        // 第一排第一个位置        int pos00;        // 第一排第二个位置        int pos01;        // 第二排第一个位置        int pos10;        // 第二排第二个位置        int pos11;        public Matrix2X2() {        }        public Matrix2X2(int pos00, int pos01, int pos10, int pos11) {            this.pos00 = pos00;            this.pos01 = pos01;            this.pos10 = pos10;            this.pos11 = pos11;        }    }    // 2个2×2的矩阵相乘得到新的矩阵    class MatrixMultiply {        public Matrix2X2 multiply(Matrix2X2 m1, Matrix2X2 m2) {            return new Matrix2X2(m1.pos00 * m2.pos00 + m1.pos01 * m2.pos10,                    m1.pos00 * m2.pos01 + m1.pos01 * m2.pos11, m1.pos10                            * m2.pos00 + m1.pos11 * m2.pos10, m1.pos10                            * m2.pos01 + m1.pos11 * m2.pos11);        }    }    MatrixMultiply multiplyer = new MatrixMultiply();    // 求Fibonacci数第N个数    public Matrix2X2 getFibo(int n) {        if (n < 0) {            return null;        }        Matrix2X2 matrix22 = null;        if (n == 1) {            matrix22 = new Matrix2X2(1, 1, 1, 0);        }        // 偶数        else if (n % 2 == 0) {            matrix22 = getFibo(n / 2);            matrix22 = multiplyer.multiply(matrix22, matrix22);        }        // 奇数        else if (n % 2 != 0) {            //提取出第一个矩阵,生下来的矩阵就是偶数个,但是要记住在最后要把提取的第一个矩阵算上。            matrix22 = getFibo((n - 1) / 2);            matrix22 = multiplyer.multiply(matrix22, matrix22);            matrix22 = multiplyer.multiply(matrix22, new Matrix2X2(1, 1, 1, 0));        }        return matrix22;    }    //原始的递归法    public static int getFibo2(int n){        {            if (n==0||n==1)            {                return n;            }            else            {                return getFibo2(n-1)+getFibo2(n-2);            }        }    }        public static void main(String[] args) {        int n = 30;        Matrix2X2 matrix = new Problem19().getFibo(n - 1);        int fn = matrix.pos00;        System.out.println(fn);        int fn2 = Problem19.getFibo2(n);        System.out.println(fn2);    }}


输出


832040832040

扩展


有网友说可以通过下面的通项公式一步求解


Fibonacci通项公式:

an=1/√[(1+√5/2) n-(1-√5/2) n]


0 0
原创粉丝点击