斐波那契数列使用递归的运行时间分析

前言

在这学期(大三上)去“蹭”了一次校招面试题,编程题中就有一道关于斐波那契数列的编程问题。如果不选择递归求解,就需要说明原因。当时还没怎么接触算法这方面的知识(笔者非科班),关于什么运行时间分析、空间复杂度分析的就是一脸懵逼,于是就描述了下可能会引发栈溢出的问题。在慢慢学习了一些算法基础之后,才明白那道题想考的就是关于运行时间的分析!


什么都别说,先“走”两步

下面是使用递归计算斐波那契数列第n项的例程:

long fib(int n) {
    if (n <= 1) {
        return 1;
    } else {
        return fib(n - 1) + fib(n - 2);
    }
}

下面开始计算运行时间:

  1. T(N)为函数fib(n)的运行时间,当n ≤ 1时,运行时间等于某个常数值,也就是执行if条件判断的时间,那么T(0) = T(1) = 1(时间单位);
  2. n ≥ 2时,T(N) = T(N - 1) + T(N - 2) + 2(2表示执行条件判断和加法的时间);
  3. fib(n) = fib(n - 1) + fib(n - 2), n ≥ 2,由归纳法可以证明T(N) ≥ fib(N),同理可证当n > 4时,fib(n) > (3 / 2) ^ n也就是说(3 / 2) ^ n = o(T(N))勘误 ,即运行时间大于随着n的增加呈指数增长的情形,可见此场景下如此使用递归效率的低下。

附:

证明1:
基准情形:T(0) = T(1) = fib(0) = fib(1) = 1
归纳假设:当0 ≤ n ≤ N,T(N) ≥ fib(N)
则只需证明T(N + 1) ≥ fib(N + 1)即可。
T(N + 1) = T(N) + T(N - 1) ,由归纳假设可得:
T(N + 1) ≥ fib(N) + fib(N - 1) => T(N + 1) ≥ fib(N) ,原命题得证。

证明2:
基准情形:fib(5) = 8 > ((3 / 2) ^ 5), fib(6) = 13 > ((3 / 2) ^ 6)
归纳假设:当4 ≤ n ≤ N时,fib(N) > ((3 / 2) ^ N)
则只需证明fib(N + 1) > ((3 / 2) ^ (N + 1)) 即可。
fib(N + 1) = fib(N) + fib(N - 1) ,由归纳假设可得:
fib(N + 1) > (3 / 2) ^ N + (3 / 2) ^ (N - 1) => fib(N + 1) > (3 / 2) ^ (N + 1) ÷ (3 / 2) + (3 / 2) ^ (N + 1) ÷ (3 / 2) ^ 2 => fib(N + 1) > (3 / 2) ^ (N + 1) * (10 / 9) => fib(N + 1) > (3 / 2) ^ (N + 1)

在给出普通数组和for循环的实现,以作对比:

for (int i = 0; i < numbersCount; i ++) {
        if (i <= 1) {
            numbers[i] = 1;
        } else {
            numbers[i] = numbers[i -1] + numbers[i - 2];
        }
}

可以很容易得到运行时间T(N) = O(N),比起使用递归,运行时间被实质性的减少了。之所以这样递归的运行时间开销很大是因为做了很多重复的工作,也就是每求一个数都需要递归到基准情形,N越大,两次起始的递归交叠程度越大,效率自然而然就降低了!

总结

在学习算法的很短的日子了就深刻体会到了一点:学好数学很重要、学好数学很重要、学好数学很重要!特别是一些数学公式的记忆,比如让你求等差数列的前项和,如果记不得公式,恐怕你就只有循环求解了,但如果你记得的话就是一个公式就可以搞定的啊!当然,这只是一个简单的比喻,但本质的道理是相同的。所以如果你还有数学课,那么且行且珍惜

勘误

在这里敲打一遍几个记法的定义,给自己长长记性:

  • 如果存在正整数c和n0使得当N≥n0时T(N) ≤ cf(N),则记为T(N) = O(f(N))。
  • 如果存在正常数c和n0使得当N≥n0时T(N) ≥ cg(N),则记为T(N) = Ω(g(N))。
  • T(N) = ⊝(h(N))当且仅当T(N) = O(h(N))和T(N) = Ω(h(N))。
  • 如果对所有的常数c存在n0使得当N > n0时T(N) < cp(N),则记为T(N) = o(p(N))。

可见,此处下这样的定义是不恰当的。

你可能感兴趣的:(算法基本功)