时间和空间复杂度(上):优化性能是否只是“纸上谈兵”?
你好,我是黄申。作为程序员,你一定非常清楚复杂度分析对编码的重要性。计算机系统从最初的设计、开发到最终的部署,要经过很多的步骤,而影响系统性能的因素有很多。
我把这些因素分为三大类:
**算法理论上的计算复杂度**
**开发实现的方案**
**硬件设备的规格**
如果将整个系统的构建比作生产汽车,那么计算复杂度相当于在蓝图设计阶段,对整个汽车的性能进行评估。如果我们能够进行准确的复杂度分析,那么就能从理论上预估汽车的各项指标,避免生产出一辆既耗油又开得很慢的汽车。可是,你也常常会发现,要准确地分析复杂度并不容易。这一讲,我来说说如何使用数学的思维,来进行系统性的复杂度分析。
基本概念
我先带你简短回顾一下几个重要概念,便于你稍后更好地理解本节的内容。
算法复杂度是一个比较抽象的概念,通常只是一个估计值,它用于衡量程序在运行时所需要的资源,用于比较不同算法的性能好坏。
同一段代码处理不同的输入数据所消耗的资源也可能不同,所以分析复杂度时,需要考虑三种情况,
**最差情况**
**最好情况**
**平均情况**
复杂度分析会考虑性能的各个方面,不过我们最关注的是两个部分,时间和空间。
时间因素是指程序执行的耗时多少,空间因素是程序占用内存或磁盘存储的多少。因此,我们把复杂度进一步细分为:
**时间复杂度**
**空间复杂度**
我们通常所说的时间复杂度是指渐进时间复杂度,表示程序运行时间随着问题复杂度增加而变化的规律。同理,空间复杂度是指渐进空间复杂度,表示程序所需要的存储空间随着问题复杂度增加而变化的规律。我们可以使用大 O 来表示这两者。
我这里不会讲太多的基本概念,而是通过数学的思维,总结一些比较通用的方法和规则,帮助你快速、准确地进行复杂度分析。
6 个通用法则
复杂度分析有时看上去很难,其实呢,我们只要通过一定的方法进行系统性的分析,就能得找正确的结论。我通过自身的一些经验,总结了 6 个法则,相信它们对你会很有帮助。
1. **四则运算法则**
2. **主次分明法则**
3. **齐头并进法则**
4. **排列组合法则**
5. **一图千言法则**
6. **时空互换法则**