前言


最近决定重学数据结构与算法,同时结合LeetCode实践来刻意练习。持续专注不变的底层知识。


以下根据《重学数据结构和算法》学习笔记整理和思考总结。

01.复杂度:如何衡量程序运行的效率?



复杂度分为:时间复杂度、空间复杂度。



时间复杂度的计算和代码的结构,代码的执行次数有关系。



空间复杂度的计算和数据结构,存储资源有关系。



复杂度和常系数无关如:O(n)、O(2n)、O(n/2)都表示O(n)复杂度



多个复杂度相加,取高次项复杂度为最终结果,如:O(n3+n2+n)那么这个复杂度就是O(n^3)



常见的一些时间复杂度有:
(1)对一个数组遍历循环,若数组长度为n,那么时间复杂度为O(n)。
(2)嵌套遍历,若外层遍历n次,内层遍历m次,则时间复杂度为O(m*n)。
(3)若两个遍历不是嵌套的,还是顺序的,那么时间复杂度依然是O(n)+O(n) = O(2n) = O(n),最终依然为O(n)。
(4)若n和程序执行的次数无关,那么时间复杂度始终为O(1);比如针对一个长度为n的字符串直接进行输出操作,不管长度为多长,始终只需输出一次。

(5)O(1)也是表示一个特殊的复杂度,为某个任务通过有限可数的资源即可完成。与输入的数量n无关。



优化时间复杂度很重要,处理10万的数据,程序结构定下的不同的时间复杂度,让计算机计算的次数是有天壤之别的。



我们给出一些经验性的结论:


  1. 一个顺序结构的代码,时间复杂度是 O(1)。
  2. 二分查找,或者更通用地说是采用分而治之的二分策略,时间复杂度都是 O(logn)。
  3. 一个简单的 for 循环,时间复杂度是 O(n)。
  4. 两个顺序执行的 for 循环,时间复杂度是 O(n)+O(n)=O(2n),其实也是 O(n)。
  5. 两个嵌套的 for 循环,时间复杂度是 O(n²)。

高手进阶:写完代码后能评估代码的复杂度,并能进行优化,追求极客精神。

02 数据结构:将“昂贵”的时间复杂度转换成廉价的空间复杂度

降低时间复杂度方法有:递归、二分法、排序法、动态规划。

降低空间复杂度:围绕数据结构。


  • 数组 数组长度决定,空间复杂度o(n)
  • 递归 根据递归的深度可达到 o(n)
  • ……
    小结:关于数据结构如何降低空间复杂度,可以根据LeetCode中爬楼梯的算法中的官方解答来进一步了解

程序优化最核心思路:


  1. 暴力解法。有没有任何时间、空间约束下,完成代码的任务开发。
  2. 无效操作处理。将代码中的无效计算、无效存储剔除,降低时间或空间的复杂度。
  3. 时空转换。设计合理的数据结构,完成时间复杂度向空间复杂度的转移。

参考资料:

​如何理解算法时间复杂度的表示法,例如 O(n²)、O(n)、O(1)、O(nlogn) 等?​