斐波那契高效算法(4种算法综合分析)

斐波那契数列问题是算法学习者必定接触到的问题。作为经典问题,首次接触时通常是作为递归算法的案例教程。

然而递归解决斐波那契。其效率低的令人发指,有人算出其时间复杂度为O(2^n)。指数级时间复杂度。

假设面试的时候面试官问你斐波那契的求解方法,你来一个递归求解,基本上能够说,你已经game over了。

那么有没有更高效的算法呢。本文将一一介绍。

以下是斐波那契的4种解法:

1.递归    时间复杂度O(2^n)

	int f(int n){
		if(n == 1 || n == 2){
			return 1;
		}
		return f(n-1) + f(n-2);
	}

2.循环    时间复杂度O(n)

    public int f(int n) {
        // write code here
        int f0 = 1;
        int f1 = 1;
        int f2 = 0;

        for(int i = 2; i < n; i++){
            f2 = f0 + f1;
            f0 = f1;
            f1 = f2;
        }
        return f2;
    }

3.矩阵求解    时间复杂度O(logn)

斐波那契的递推公式能够表示成例如以下矩阵形式。所以其

      

所以依据矩阵的分治算法。能够在O(logn)时间内算出结果。

笔试问题:

对于斐波拉契经典问题。我们都很熟悉。通过递推公式F(n) = F(n - 1) + F(n - 2),我们能够在线性时间内求出第n项F(n),如今考虑斐波拉契的加强版,我们要求的项数n的范围为int范围内的非负整数,请设计一个高效算法,计算第n项F(n)。

第一个斐波拉契数为F(0)
= 1。

给定一个非负整数,请返回斐波拉契数列的第n项,为了防止溢出,请将结果Mod 1000000007。

    long[][] f = new long[][]{{0,1},{1,1}};
    public int getNthNumber1(int n) {
    	if(n == 0)
            return 1;
        if(n == 1)
            return 1;
        f = pow(n,f);

		return (int) f[1][1];
    }

    private long[][] pow(int n,long[][] f){
    	if(n == 1)
    		return f;

    	if(n == 2){
    		return fun(f,f);
    	}

    	if( n % 2 == 0){//偶数
    		f = pow(n/2,f);
    		return fun(f, f);
    	}else{
    		return fun(pow(n/2,f),pow(n/2 + 1,f));
    	}
    }

    private long[][] fun(long[][] f,long[][] m){
    	long[][] temp = new long[2][2];
    	temp[0][0] = (f[0][0]*m[0][0] + f[0][1]*m[1][0])%1000000007;
    	temp[0][1] = (f[0][0]*m[0][1] + f[0][1]*m[1][1])%1000000007;
    	temp[1][0] = (f[1][0]*m[0][0] + f[1][1]*m[1][0])%1000000007;
    	temp[1][1] = (f[1][0]*m[0][1] + f[1][1]*m[1][1])%1000000007;
    	return temp;
    }

4.公式求解  时间复杂度O(1)

对,你没看错。斐波那契数列是有求解公式的。其通项公式例如以下:

所以,不论什么斐波那契数都能够在O(1)时间内计算出来,可是有一点,由于牵涉到无理数。所以无法保证精度。

详细代码略。

综上,眼下代码效率最高也最准确的,是第3种矩阵求解方法,笔试面试时务必掌握。

【完】

时间: 2024-10-11 11:24:24

斐波那契高效算法(4种算法综合分析)的相关文章

Fibonacci series(斐波纳契数列)的几种常见实现方式

费波那契数列的定义: 费波那契数列(意大利语:Successione di Fibonacci),又译费波拿契数.斐波那契数列.斐波那契数列.黄金分割数列. 在数学上,费波那契数列是以递归的方法来定义: (n≧2) 用文字来说,就是费波那契数列由0和1开始,之后的费波那契系数就由之前的两数相加. 首几个费波那契系数是:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233-- 特别指出:0不是第一项,而是第零项. 下面是费波那契数列的几种常见编程实现:

斐波那契数列的三种时间复杂度

/*前边两个为一种做法*/ /*后边有另外的做法(差分方程以及利用矩阵去做)*/ //***************************************************//***************************************************//*************************************************** 第一种做法 这是2018王道数据结构考研复习指导的第一章思维拓展的题目. 关于斐波那契数列的简介:

实现斐波那契数列的三种方式

首先说说斐波那契数列:从文字上说,费波那西数列由0和1开始,之后的斐波那契系数就由之前的两数相加,数列形式如下:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584,………………在数学上,是以递归的方法来定义:F(0)=0F(1)=1F(n)= F(n-1)+ F(n-2) 实现需求:输入序号n返回得到对应斐波那契数程序实现1——函数迭代 public int fnType1(int n)thro

斐波那契数的两种实现方式———1.递归实现,2迭代实现

对于斐波那契数,若是采用递归的算法,每个递归调用都将触发另外两个递归调用,而这两个中调用任意一个还会触发另外两个的调用.递归调用的时间复杂度O(2^N),空间复杂度为O(N),所以在计算略大的数会花费一定的时间和空间.递归程序如下: #include<iostream> using namespace std; unsigned long long Fib(size_t num) {     if (num < 2)     {         return num;     }    

java程序员到底该不该了解一点算法(一个简单的递归计算斐波那契数列的案例说明算法对程序的重要性)

为什么说 “算法是程序的灵魂这句话一点也不为过”,请看下面这个简单的案例 1 package recursion; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 import org.junit.Test; 7 8 /** 9 * @author: MengXianman 10 * @creationTime: 2017年11月27日 上午9:47:51 11 * @description: 斐波那契数列结合备忘录算法的简单使

【转】Fibonacci 斐波纳契堆优化 Dijkstra 最短路径算法

话不多说,拿来主义,直接上代码! PS:打印最短路径我还不晓得怎么加,如有哪位大神知道,还请mark一下! 1 /*********************************************************************** 2 * File: FibonacciHeap.java 3 * Author: Keith Schwarz ([email protected]) 4 * 5 * An implementation of a priority queue

算法笔记_001:斐波那契数的多种解法

本篇文章解决的问题来源于算法设计与分析课程的课堂作业,主要是运用多种方法来计算斐波那契数.具体问题及解法如下: 一.问题1: 问题描述:利用迭代算法寻找不超过编程环境能够支持的最大整数的斐波那契数是第几个斐波那契数.(Java: 231-1 for int, 263-1 for long) 解决方案:针对问题1,此处要使用迭代法来解决,具体实现代码如下: //用迭代法寻找编程环境支持的最大整数(int型)的斐波那契数是第几个斐波那契数 public static int max_int_iter

算法导论第十九章 斐波那契堆

<算法导论>第二版中在讨论斐波那契堆之前还讨论了二项堆,但是第三版中已经把这块的内容放到思考题中,究极原因我想大概是二项堆只是个引子,目的是为了引出斐波那契堆,便于理解,而且许多经典的算法实现都是基于斐波那契堆,譬如计算最小生成树问题和寻找单源最短路径问题等,此时再把二项堆单独作为一章来讲显然没有必要.类似的堆结构还有很多,如左倾堆,斜堆,二项堆等,下次我打算开一篇博客来记录下它们的异同点. 一.摊还分析(第十七章) 这些高级的数据结构的性能分析一般是基于一个技术——摊还分析,可以理解成一种时

求解斐波那契数列的第n项

对于Fibonacci数列,1,1,2,3,5,8,12,...求解第n项值,我们通常用的是递归算法,即递推式f(n) = f(n-1)+f(n-2).然而这其实是一种效率极低的算法,当n达到41时,就已经需要1s左右,随着n的增加,时间是指数级增长的. 因为该递归算法有太多的重复计算,如下图所示,所用时间T(n) = T(n-1)+T(n-2)+Θ(1),可以知道T(n)有Ω((3/2)n)的下界,T(n)<O(2^n),可以看到这是指数级的时间复杂度. 具体代码实现如下: Elemtype