算法的复杂度分析
事后分析估算方法
先根据算法编好程序,运行程序比较时间/空间大小。很明显的不靠谱
事前分析估算方法
一个高级程序语言编写的程序在计算机运行所消耗的时间取决于:
- 算法本身
- 编译产生的代码质量
- 问题的输入规模
- 机器执行指令的速度
编译和执行速度取决于软件硬件,所以一个算法的运行时间取决于算法的好坏和问题输入规模。
算法比较实例
- 算法A:2n方
- 算法B:2n方 + 3n + 1
可以理解为算法A,进行了两次两重for循环,算法B进行了两次两重for循环加3次for循环,一次赋值或运算操作。
在n无限大时,判断一个算法的效率函数中的常数和其他次项常常可以忽略,而更应该关注最高阶项的阶数。
所以,我们不计较变量声明,循环索引,终止条件,字符打印等等操作。
大 O 复杂度表示法
我们假设每行语句的执行一遍的时间是一个单位时间(unit_time)。所以整段代码总的执行时间:
T(n) = (2n+1)*unit_time
尽管我们不知道 unit_time 的具体值,但是通过公式,我们知道所有代码的执行时间 T(n) 与每行代码的执行次数 n 成正比。
因此我们可以引出这么条公式:T(n) = O(f(n)) ,于是代码执行时间会演变成:T(n) = O(2n+1) = O(n)
O是同阶无穷小,简言之就是 T(n) 和 f(n) 趋于零的速率一致。
推导大 O 阶方法
- 用常数1取代运行时间中的所有加法常数
- 在上一步的基础上,只保留最高阶
- 去除常数就是最后结果
- 常数阶都是O(1)
平均情况和最坏情况
在 n 个元素的数组中查找一个数字,有可能第一个就是也有可能最后一个才是,在没有特殊说明情况下,我们指的都是最坏时间复杂度
算法空间复杂度
可以使用空间来换时间,判断某一年是否为闰年可以每次都直接计算,也可以写入全部年份,闰年赋值为1或者为0, S(n) = O(f(n)),一次执行次数等于一个单位内存即可