数据结构和算法经典100题-第19题

最近在忙着学习redis的源代码,总算把《redis设计和实现》看完了,下面该详细写redis的代码分析了。好久木有更新算法题了,现在继续更新算法题,看一下题目:
第19题

题目:定义Fibonacci数列如下:
/ 0 n=0
f(n)= 1 n=1
\ f(n-1)+f(n-2) n=2

输入n,用最快的方法求该数列的第n项。


记得在遥远的7年多前,刚上大一学习C语言那会,谭浩强的那本绿皮C语言程序设计上有这个问题:当时是为了讲解递归,用的是这个例子来说明的。
那自然就想到用递归解决这个问题,但其实递归解决这个问题并不是好的办法。
可以画一棵递归树:
f(10)
/ \
f(9) f(8)
/ \ / \
f(8) f(7) f(7) f(6)
/ \ / \
f(7) f(6) f(6) f(5)
Ok,我们看到用递归树解决这个这个问题很笨,做了很多重复的计算:用递归解决这个问题的代码大概是这样的:

long recursionOfFibonacci(long n) {
    if (2 < n ) {
        return recursionOfFibonacci(n-1) + recursionOfFibonacci(n-2);
    } else if(0 < n) {
        return 1;
    }

    return 0;
}

看到递归树,我们大概就会想到用缓存把中间计算过程缓存下来,这样的代码页不难实现,大概是这样的:

// 时间复杂度是O(n)
long cacheOfFibonacci(long n) {

    if (0 == n ) {
        return 0;
    } else if(1 == n || 2 == n) {
        return 1;
    }

    long cache[2];
    cache[0] = 1;
    cache[1] = 1;
    long tmp = 0;

    // 时间复杂度是O(n)
    for (long i = 3; i < n; i++) {
        tmp = cache[1] + cache[0];
        cache[1] = cache[0];
        cache[0] = tmp;
    }

    return cache[0] + cache[1];

    return 0;
}

本人呢,也比较笨,没有想到别的办法,网络上搜了一下看到有一种利用矩阵乘法把一维递推优化到O(lgn)的。OK,本人真是跪了,转一下这位大神的分析:
http://zhedahht.blog.163.com/blog/static/25411174200722991933440/


OKay,路漫漫…吾将上下而求索…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值