复杂度
复杂度是一个关于输入数据量n的函数,是衡量代码运行效率的重要度量因素。复杂度从维度可以划分为时间复杂度、空间复杂度。
时间复杂度
时间复杂度是指一个算法在运行过程中所花费的时间。
空间复杂度
空间复杂度是指一个算法在运行过程中临时占用的存储空间大小。
复杂度需要遵循的原则
1、复杂度与具体的常系数无关
例如O(n) 和 O(2n) 表示的复杂度是一样的。因为O(2n) 等于 O(n+n),也等于 O(n) + O(n)。也就是说,一段 O(n) 复杂度的代码只是先后执行两遍 O(n),其复杂度是一致的。
2、多项式级的复杂度相加的时候,选择高者作为结果
例如 O(n²)+O(n) 和 O(n²) 表示的是同样的复杂度。具体分析一下就是,O(n²)+O(n) = O(n²+n)。当 n 越来越大时,n²+n 和 n² 中间的差值可以忽略不计。
3、O(1) 也是表示一个特殊复杂度
O(1) 含义为某个任务通过有限可数的资源即可完成。即与输入数据量 n 无关。
常见算法的时间复杂度总结
1、一个顺序结构的代码,时间复杂度是 O(1)
2、分查找,或者更通用地说是采用分而治之的二分策略,时间复杂度都是 O(logn)
3、一个简单的 for 循环,时间复杂度是 O(n)
4、两个顺序执行的 for 循环,时间复杂度是 O(n)+O(n)=O(2n),由于复杂度和常量系数无关,所以其实也是 O(n)
5、两个嵌套的 for 循环,长度相等,时间复杂度是 O(n²)
6、两个嵌套的 for 循环,长度不相等,时间复杂度是 O(m*n)
优化方法
1、时间昂贵、空间廉价
代码效率的瓶颈可能发生在时间或者空间两个方面。如果是缺少计算空间,花钱买服务器就可以了。这是个花钱就能解决的问题。相反,如果是缺少计算时间,只能投入宝贵的人生去跑程序。
2、降低复杂度的步骤
第一步:暴力解法。假设最坏的情况,在没有任何时间、空间约束下,完成代码任务的开发。
第二步:无效操作处理。将代码中的无效计算、无效存储剔除,降低时间或空间复杂度。
第三步:时空转换。设计合理数据结构,完成时间复杂度向空间复杂度的转移。