在学校里学习完数据结构和算法两门课之后,我就再也没有用到过它们,但它们不只是用来应付面试的手段,更是成为优秀程序员必须具备的基础,所以今天开始重新学习。
参考资料
- 拉勾网课程《重学数据结构与算法》 公瑾
- 《算法(第4版)》 谢路云 译
拉勾网课程是付费课程,所以本笔记中将会尽量不出现课程提供的文档等资料。《算法(第4版)》的英文版本可以从官网上免费查看,是一份相当好的资料,地址如下:
https://algs4.cs.princeton.edu/home/
时间复杂度与空间复杂度的一些结论
时间复杂度与代码结构有关。
空间复杂度与数据结构有关。
单层循环时间复杂度一般为O(n),双层循环为O(n^2),顺序的两个循环,时间复杂度为O(2n)。
顺序结构时间复杂度为O(1),二分策略时间复杂度为O(log n)。
时间复杂度与常数系数无关,O(2n)也是O(n)。
复杂度相加时取高者,O(n^2 )+O(n)=O(n^2)。
O(1)表示任务与算例个数n无关。
记住上面的结论,就能很轻松地计算一些时间复杂度。
实际应用时的经验结论:时间复杂度比空间复杂度更重要一些。消耗存储空间大可以通过增加存储空间解决。消耗时间多虽然也可以通过换用计算能力更强的CPU或GPU来解决,但归根结底是价格更贵。而且需要计算的数据n越大,时间复杂度低的程序优势就越大。假设有程序A时间复杂度为O(n),程序B为O(n^2),即使更换的新CPU计算能力是原来的两倍,跑程序B的话最多也就减少一半时间,但如果把程序B优化成程序A,就能把原来消耗的时间开根号了。
如何利用复杂度来优化程序
常用的降低时间复杂度的方法:递归、二分法、排序算法、动态规划等。
降低空间复杂度的方法:尽量用不复杂的数据结构。
进行优化时,可以尽量把时间复杂度转移到空间复杂度上,通过牺牲空间换取时间。
程序优化的过程:
- 暴力解法:在没有限制的情况下完成开发。
- 处理无效操作:删掉代码中的无效存储和无效计算,降低时间和空间复杂度。
- 时空转换:设计合理数据结构,将时间复杂度转移到空间复杂度上。