我们知道算法的效率是判断一个程序好坏的重要标准,在当今的社会,一个程序运行速度的快慢决定着人们对这个程序的好感已及认可度,那么我们都是如何来进行算法效率的表示的呢?
这就是我们接下来要讲的时间复杂度!
我们先来讲一个经典的例子,斐波那契数列大家都有所耳闻,就是1+1+2+3+5......
我们实现一个斐波那契数列有许多种办法,我们可以使用递归,也可以使用循环,这里我使用递归来举例子(如下图所示)
通过上述代码我们来实现找到第n项的斐波那契数,我们会发现 整个代码实现起来非常轻松,没有多少步骤就是写完了。
唉,既然它对我们来说这么方便,那我们是不是直接无脑递归就行了呢?答案是错误的。
这里我们再来举一个例子(如下图所示)
当我们输入50的时候就会发现代码半天都没有 运算出结果,是计算机太没用了吗?连第50项都算不出来?答案当然不是,计算机的运算速度可是相当快的,一台普通的计算机一秒少说都能进行上亿次的计算,那为何它还会被第50项困住?唉,这就可以用我们的时间复杂度来解释了。
时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道。但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个分析方式。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。
通俗的来讲,时间复杂度计算的是你代码实现的思维。
比如上述的例子。我们用递归来完成的代码到底经历了多少次计算,我们可以简单的画一个图来分析它。
我们会发现同样的目的,我们如果使用for循环的思想,可能两三次就想出来了,但我们用递归的思想。计算机却调用了Fib函数8次,这是因为递归的状态下我们的计算是呈现指数级增长。
像这样的算法它的时间复杂度就是O(2^N)时间复杂度的计算我们采用的是估算的方法,使用的是大O的渐进表示法。
所以,我们认为的几十次计算计算机可是算了大概2^50次,这计算量就非常恐怖了。
那for循环在这里的时间复杂度是多少呢?注意:看思想。
for循环我们是采用遍历的方式来找第n项的斐波那契数。(代码如下)
这里,我们会发现,虽然结果是错误的但计算机很快就算出来了,结果错误是因为它的值超出了存储空间的大小, 那么在这里,代码的时间复杂度是多少呢?——O(N)。
因为我们想找第几项就大概找对应的几次嘛,所以计算时间复杂度,得知代码的逻辑、思想至关重要!