一、算法复杂度
算法复杂度,即算法在编写成可执行程序后,运行时所需要的资源,资源包括时间资源和内存资源。
同一问题可用不同算法解决,而一个算法的质量优劣将影响到算法乃至程序的效率。算法分析的目的在于选择合适算法和改进算法。一个算法的评价主要从时间复杂度和空间复杂度来考虑。
OK!看到此处,我想大家应该简单明白了算法复杂度是怎么一回事。如果你是计算机科班或者数学专业出身恰巧你的成绩又很不错的,那你就不需要继续往下看了。因为作者根本不是学计算机出身的,对于这些高深的知识,在查阅很多资料后也是似懂非懂,更不能向大家很好的阐述里面的道理。但又不想跟风去复制粘贴百度上的东西。所以,我想既然看到这里的读者应该绝大多数都是似懂非懂的。我认为在这么摆事实、讲道理就没意思了。如果能用现实中身边的例子来说明这些,那也是更好不过了。当然,作者若有机会也会好好折腾一番弄明白这里面究竟讲的是个啥。我想这也符合每一个力求上进的骚年所具备的心态。
1、时间复杂度
通过查看百度百科也大致了解到时间复杂度的大致意思。还有那些抽象的字母表达式。对于那些东西我就不在复制粘贴到此了。不如用更简洁易懂的实例来说说这里面的大致意思,在之前的一篇貌似是大学老师的博客里看到很有意思的说明。
假设CPU在短短几年内,速度提高了10呗。虽有有摩尔定律,这其实已经很夸张了。而我们的某个算法本可以写出时间复杂度是O(n)的算法,却写成了O(n^2)的程序,仅仅因为容易想到,也容易写。即在O(n^2)的时间复杂度程序下,速度其实只提高了10(根下100=10)倍。而对于O(n)时间复杂度的算法来说,那才是真的100倍。也就是说,一台老式CPU的计算机运行O(n)的程序和一台速度提高100倍新式CPU运行O(n^2)的程序,最终效率高的胜利方却是老式CPU的计算机。原因在于算法的优劣直接决定了程序运行的效率。由此可见,时间复杂度是非常重的一个衡量算法好快的事前估算的方法。
关于时间复杂度的计算方法不再赘述。这里说一下最坏情况与平均情况的时间复杂度。当你早上起床准备出去吃饭上课的时候,到了宿舍楼下才突然响起来,手机忘记带了。这年头,钥匙、钱包、手机三大件,哪样也不能少啊。回宿舍打开门一看,手就在对门的窗台上放着。这当然是比较好的,基本没花什么时间。可是如果不在那里,你就得到处找。可能翻遍了书桌和壁橱,等找到的时候都快8点了,匆匆去上课,早饭算是泡汤了。找东西有运气好的时候,也有怎么都找不到的时候,但在现实中,通常我们碰到的绝大多数既不是最好也不最坏的,所以算下来是平均情况居多。
算法分析也是如此,在n个随即数中查找某个数字,最好的情况是第一个数字就是,此时时间复杂度为O(1),若最后一个数字才是我们要找的,那么时间复杂度是O(n),这是最坏的情况。而平均运行时间是从概率的角度看,若数字在每一个位置都可能出现,则平均查找次数为n/2次。
平均运行时间是所有情况中最有意义的,因为它是期望的运行时间。可现实中,平均运行时间很难通过分析得到,一般都是通过运行一定数量的实验数据后估算而来的。而最坏运行时间是一种保证,那就是运行时间不会再坏了。在应用中,这是最重要的需求,通常,除非特别指定,我们提到的运行时间都是最坏情况下的运行时间。即,时间复杂度是最坏情况下的时间复杂度。
常见的算法时间复杂度由小到大依次为:
O(1)<O(log2n)<O(n)<O(n log2 n)<O(n^2)<O(n^3)<O(2^n)
2、空间复杂度
空间复杂度的概念就简单许多了,简单来说就是在执行算法时所占用的内存资源。除去专业术语和计算方法,用大白话还真不知道怎么说的更多一些。
值得一提:
对于一个算法,其时间复杂度和空间复杂度往往是相互影响的。当追求一个较好的时间复杂度时,可能会使空间复杂度的性能变差,即可能导致占用较多的存储空间;反之,当追求一个较好的空间复杂度时,可能会使时间复杂度的性能变差,即可能导致占用较长的运行时间。
就好像我们解决一个问题时,有很多种解决办法,这里就对应了很多种算法。在选择某一种算法时,我们应该分析这种算法所带来的成本与收益。因为每一种算法都有其自己的特性,如果时间节省了,但就可能浪费空间。反之亦然。
事后感慨:
经过几个简单的算法的洗礼,突然发现之前做的东西太简单了。并不是说之前做的东西没有价值,而是从做技术的职业生涯来看,普通的编程也许很快就会遇到瓶颈。但研究了几个算法之后。似乎看到了一条更长远的道路,相比代码的累加,这种通过精心的设计而达到的优化效果显得更有趣味和挑战性。由此感慨,要学的东西还太多太多,不仅仅是经验的累加,更应该是智力和思维的突破。