斐波那契数列

描述

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

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

前2个数是 0 和 1 。

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

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

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

样例

给定 1,返回 0

给定 2,返回 1

给定 10,返回 34

思路

斐波那契数列算是一个很常见的典型递归问题了,直接就可以很轻松地根据定义写出代码:

public int fibonacci(int n) {
// write your code here
if (n == 1) return 0;
if (n == 2) return 1;
return fibonacci(n - 1) + fibonacci(n - 2);
}

然而得到的结果却是Time Limit Exceeded

显然,问题自然是出在递归的身上,于是开始分析一下:

递归算法在程序中运行的时候会占用不少的栈空间,这一点是毋庸置疑的,但是这并不是最大的问题,最大的问题是这个代码中存在大量的重复计算

n > 2时,在计算f(n)显然会计算f(n - 1) + f(n - 2),当计算完f(n - 1)后,程序又会从头开始计算f(n - 2),然而事实是f(n - 2)在计算f(n - 1)的过程中就已经知道结果了,程序却从头算起,这就造成了重复计算。当n数值小的时候并不要紧,一旦n的数据越来越大,所浪费的时间也就越来越多,这也就是这次超时的根本所在。

知道问题后,我们就很容易能想出对策了,既然已经算出了值却没有使用,那么我们可以将算出的结果保存起来,方便下次或者将来的使用。这里我选择了使用List来存放计算的结果,代码如下:

代码

class Solution {
/**
* @param n: an integer
* @return an integer f(n)
*/
public int fibonacci(int n) {
// write your code here
List<Integer> list = new ArrayList<Integer>();
list.add(0);
list.add(1);
for (int i = 0; i < n; i++) {
if (list.size() < (i + 1)) {
list.add(list.get(i - 1) + list.get(i - 2));
}
}
return list.get(n - 1);
}
}

写在最后

递归算法因为其结构清晰,所以阅读起来更容易理解,但是却往往带来性能上的缺失。

因此,在写出递归算法后,应尽量考虑是否还有可优化的空间。

比如这次的题目,当n越来越大,其带来的性能损耗将会是非常可怕的。

最近在看动态规划的时候,也体会到了这种思想。

【LintCode·入门】斐波那契数列的更多相关文章

  1. 【未通过】LintCode #366 斐波纳契数列

    实现: public class Solution { /** * @param n: an integer * @return: an ineger f(n) */ public int fibon ...

  2. python入门斐波那契数列之迭代,递归

    迭代 def fab(n): a1=1 a2=1 a3=1 if n < 1 : print("输入有误!") return -1 while n-2 > 0 : a3 ...

  3. lintcode:Fibonacci 斐波纳契数列

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

  4. Android NDK入门实例 计算斐波那契数列一生成jni头文件

    最近要用到Android NDK,调用本地代码.就学了下Android NDK,顺便与大家分享.下面以一个具体的实例计算斐波那契数列,说明如何利用Android NDK,调用本地代码.以及比较本地代码 ...

  5. C++入门经典-例6.18-数组的动态分配,动态获得斐波那契数列

    1:有时在获得一定的信息之前,我们并不确定数组的大小.动态分配数组则可以使用变量作为数组的大小,使数组的大小符合我们的要求. 2:科普一下斐波纳契数列:斐波那契数列指的是这样一个数列 1, 1, 2, ...

  6. LintCode 斐波纳契数列

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

  7. AcWing 21. 斐波那契数列

    题目地址 https://www.acwing.com/solution/acwing/content/2896/ 题目描述输入一个整数 n ,求斐波那契数列的第 n 项. 假定从0开始,第0项为0. ...

  8. 力扣 - 剑指 Offer 10- I. 斐波那契数列

    题目 剑指 Offer 10- I. 斐波那契数列 思路1(递归 / 自顶向下) 这题是很常见的一道入门递归题,可以采用自顶向下的递归方法,比如我们要求第n个位置的值,根据斐波那契数列的定义fib(n ...

  9. C#求斐波那契数列第30项的值(递归和非递归)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

随机推荐

  1. JAVA基础知识总结:五

    一.初步认识数组 1.理解数组 数组是用来存储相兼容数据类型的定长的容器 特点: a.只能存放相兼容数据类型,不能存放多种数据类型 b.可以存放基本数据类型和引用数据类型 c.数组是定长的,一旦被初始 ...

  2. Linux上安装二进制文件MySQL详解

    前言:昨天晚上搞了很久,终于搞清楚mysql的安装配置了,我真是太low了.当我在云服务器上登进Mysql时,真是高兴哈哈,咱一步一步来,彻底搞懂Mysql的安装配置. 我的安装环境: 阿里云服务器 ...

  3. sublime text3 开发必备插件

    1,Package Control 通俗易懂地说,这个是你在完成安装SublimeText后必须安装的东西.你问为什么?因为有了这个特殊的"插件包",你可以很容易地安装.升级.删除 ...

  4. 聊聊pthread_cond_wait的虚假唤醒

    使用条件变量时,仅仅从pthread_cond_wait返回就说条件成立是不恰当的.我们正确使用pthread_cond_wait的唯一方式是当线程被从pthread_cond_wait唤醒时,再检查 ...

  5. Java基础笔记4

    数组 有一组相同数据类型的数据. 数据类型[] 数组名称=new 数据类型[长度]; //为该数组开辟空间. 数据类型[] 数组名称={值,值}; 求数组的长度 数组名称.length; 获取数组中的 ...

  6. 前端性能优化jQuery性能优化

    一.使用合适的选择器 $("#id"); 1.使用id来定位DOM元素无疑是最佳提高性能的方式,因为jQuery底层将直接调用本地方法document.getElementById ...

  7. 数据结构--KMP算法总结

    数据结构—KMP KMP算法用于解决两个字符串匹配的问题,但更多的时候用到的是next数组的含义,用到next数组的时候,大多是题目跟前后缀有关的 . 首先介绍KMP算法:(假定next数组已经学会, ...

  8. Exclusive-OR(带权并查集)

    Exclusive-OR Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...

  9. Boolean 相关

    Boolean(something) 会把里面的变量转化为布尔型   当我们用if(something)判断的时候,相当于调用了这个函数   转化规则如下 DATA TYPE VALUES CONVE ...

  10. 《剑指offer》面试题的Python实现

    <剑指Offer>是很多程序员面试前要看的书,但里面的算法都是基于C++实现的,最近用了三周左右时间,用Python完成了里面几乎所有的算法题,由于时间以及个人水平均有限,或许会有部分问题 ...