算法题目

查找斐波纳契数列中第 N 个数。

所谓的斐波纳契数列是指:

* 前2个数是 0 和 1 。

* 第 i 个数是第 i-1 个数和第i-2 个数的和。

斐波纳契数列的前10个数字是:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34 …

分析

斐波那契数列满足公式f(n) = f(n-1) + f(n-2),n > 0。这里我们的第一想法是使用递归,可是直接翻译公式出来的递归调用是这样的:

int fib(int n) {
if (n == 1) {
return 0;
}
if (n == 2){
return 1;
} return fib(n - 1) + fib(n - 2);
}

可是这个函数的事件复杂度恰好是最糟糕的指数级。怎么来证明它是指数级呢?

你可以先用一些测试数来测试一下这个方法:

当n = 40时,大概就需要0.5秒才能计算出来;

当n 为50时,需要等很久才能计算出实际的值。

下面来推导它的时间复杂度。

对于斐波那契数,有定理 :当n >= 0时,Fn < (5/3)n

首先使用归纳法来证明。对于基准情形,F1 = 0 < 5/3,F2 = 1 < 5/3。

然后假设i = 1,2,3,…,n 成立;这就是归纳假设。那么我们只需要证明出Fn+1 < (5/3)n+1 即可。

根据公式我们可以得出Fn+1 = Fn + Fn-1

推到过程如下:

Fn+1 < (5/3)n + (5/3)n-1

Fn+1 < (3/5)(5/3)n+1 + (3/5)2(5/3)n+1

Fn+1 < (24/25)(5/3)n+1 < (5/3)n+1

得证 Fn+1 < (5/3)n+1

同样的证明过程,可以证明出当n > 4时, Fn > (3/2)n

而T(n) = T(n-1) + T(n-2) + 3。

T(n) >= fib(n) >= (3/2)n

因此这个函数的运行时间是以指数的速度增长。

可能有点不同的是,有的斐波那契数列是从1,1,2,3,…. 开始,所以有些微的差别。

这只是对级数做了一次平移。我们可以找一些方便证明的情况来证明。

更优解法

其实上面的递归违反了递归的合成效益法则,才导致了运行时间的指数级增长。

递归的四条基本准则:

1、基准情形。必须有总有某些基准情形,它无须递归就能解出。

2、不断推进。对于那些需要递归求解的情形,每一次递归调用都必须要使求解状况朝接近基准情形的方向推进。

3、设计法则。假设所有的递归调用都能运行。

4、合成效益法则。在求解一个问题的同一示例时,切勿在不同的递归调用中做重复性的工作。

我们可以利用一个简单的for 循环来求解第N个斐波那契数。

int fibonacci(int n) {
if (n == 1) {
return 0;
} if (n == 2) {
return 1;
} int a = 0;
int b = 1;
int c = 0;
for (int i = 3; i < n + 1; i++) {
c = a + b;
a = b;
b = c;
}
return c;
}

使用两个变量分别保存f(n-1) 和f (n-2),然后从基准情况开始往第 n 个数推进。

改进后的函数时间复杂度是O(n),运行时间大概是 (3n - 1)大大减少了运行时间。

算法之路(三)----查找斐波纳契数列中第 N 个数的更多相关文章

  1. Java算法求最大最小值,冒泡排序,斐波纳契数列一些经典算法<不断更新中>

    清明在家,无聊,把一些经典的算法总结了一下. 一.求最大,最小值 Scanner input=new Scanner(System.in); int[] a={21,31,4,2,766,345,2, ...

  2. lintcode:Fibonacci 斐波纳契数列

    题目: 斐波纳契数列 查找斐波纳契数列中第 N 个数. 所谓的斐波纳契数列是指: 前2个数是 0 和 1 . 第 i 个数是第 i-1 个数和第i-2 个数的和. 斐波纳契数列的前10个数字是: 0, ...

  3. LintCode 斐波纳契数列

    查找斐波纳契数列中第 N 个数. 所谓的斐波纳契数列是指: 前2个数是 0 和 1 . 第 i 个数是第 i-1 个数和第i-2 个数的和. 斐波纳契数列的前10个数字是: 0, 1, 1, 2, 3 ...

  4. Java算法求最大最小值,倒序,冒泡排序,斐波纳契数列,日历一些经典算法

    一,求最大,最小值 int[] a={21,31,4,2,766,345,2,34}; //这里防止数组中有负数,所以初始化的时候给的数组中的第一个数. int max=a[0]; int min=a ...

  5. java斐波纳契数列

    //斐波纳契数列,又称黄金分割数列,指的是这样一个数列:1.1.2.3.5.8.13.21.-- 这个数列从第三项开始,每一项都等于前两项之和. public class DiGui { public ...

  6. HDU 4639 Hehe(字符串处理,斐波纳契数列,找规律)

    题目 //每次for循环的时候总是会忘记最后一段,真是白痴.... //连续的he的个数 种数 //0 1 //1 1 //2 2 //3 3 //4 5 //5 8 //…… …… //斐波纳契数列 ...

  7. 用PHP迭代器来实现一个斐波纳契数列(转)

    斐波纳契数列通常做法是用递归实现,当然还有其它的方法.这里现学现卖,用PHP的迭代器来实现一个斐波纳契数列,几乎没有什么难度,只是把类里的next()方法重写了一次.注释已经写到代码中,也是相当好理解 ...

  8. 10、end关键字和Fibonacci series: 斐波纳契数列

    # Fibonacci series: 斐波纳契数列 # 两个元素的总和确定了下一个数 a, b = 0, 1 #复合赋值表达式,a,b同时赋值0和1 while b < 10: print(b ...

  9. HDU 5914 Triangle 斐波纳契数列 && 二进制切金条

    HDU5914 题目链接 题意:有n根长度从1到n的木棒,问最少拿走多少根,使得剩下的木棒无论怎样都不能构成三角形. 题解:斐波纳契数列,a+b=c恰好不能构成三角形,暴力就好,推一下也可以. #in ...

随机推荐

  1. [LeetCode] Find Largest Value in Each Tree Row 找树每行最大的结点值

    You need to find the largest value in each row of a binary tree. Example: Input: 1 / \ 3 2 / \ \ 5 3 ...

  2. pyqt4 写动画不能播放问题集合

    最近在学习动画,真的真的是血泪史,百度基本是0资源,各种在谷歌外国大佬的英文中躺过一个一个血坑....... 这是随便写的一个动画功能调试窗口..... 问题现象: 点击食灵,没反应,写的动画不能生成 ...

  3. 【Swfit】Swift与OC两种语法写单例的区别

    Swift与OC两种语法写单例的区别 例如写一个NetworkTools的单例 (1)OC写单例 + (instancetype)sharedNetworkTools { static id inst ...

  4. [Luogu 2090]数字对

    Description 对于一个数字对(a, b),我们可以通过一次操作将其变为新数字对(a+b, b)或(a, a+b). 给定一正整数n,问最少需要多少次操作可将数字对(1, 1)变为一个数字对, ...

  5. [SDOI2009]虔诚的墓主人

    题目描述 小W是一片新造公墓的管理人.公墓可以看成一块N×M的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地. 当地的居民都是非常虔诚的基督徒,他们愿意提前为自己找一块合适墓地. ...

  6. codeforces 651C Watchmen

    Watchmen are in a danger and Doctor Manhattan together with his friend Daniel Dreiberg should warn t ...

  7. [ZJOI2006]超级麻将

    题目描述 很多人都知道玩麻将,当然也有人不知道,呵呵,不要紧,我在这里简要地介绍一下麻将规则: 普通麻将有砣.索.万三种类型的牌,每种牌有1~9个数字,其中相同的牌每个有四张,例如1砣~9砣,1索~9 ...

  8. 洛谷mNOIP模拟赛Day1-分组

    传送门 首先是贪心的思路 从后向前选,能多选就多选, 理由:数字越少肯定越优,同时间隔尽量向前推,字典序尽量小 对于K==1,枚举1~512直接判断 对于K==2,需要用镜像并查集,来刻画" ...

  9. 【Codeforces 851D Arpa and a list of numbers】

    Arpa的数列要根据GCD变成好数列. ·英文题,述大意:      给出一个长度为n(n<=5000000)的序列,其中的元素a[i]<=106,然后输入两个数x,y(x,y<=1 ...

  10. 例10-4 uva10791(唯一分解)

    题意:求最小公倍数为n的数的和的最小值. 如12:(3,4),(2,6),(1,12)最小为7 要想a1,a2,a3……an的和最小,要保证他们两两互质,只要存在不互质的两个数,就一定可以近一步优化 ...