算法第一课:复杂度引入

算法复杂度

算法复杂度分两种,时间复杂度和空间复杂度。分别代表了算法的用时,以及算法所占用的内存空间。复杂度越小,运行效率越高。

复杂度表示法

一般用大写字母 \(O\) 表示,称为大 \(O\) 表示法。比如 \(O(n)\)\(O(n^2)\) 等。这里的 \(n\) 代表了算法的输入规模,比如数组的长度,链表的长度等。\(n\)\(n^2\) 表示了算法的复杂度,\(n\) 表示线性复杂度,\(n^2\) 表示平方复杂度。

复杂度分级

常见的复杂度,按照性能从高到低排序如下:

  1. 常数阶 \(O(1)\)
  2. 对数阶 \(O(logn)\)
  3. 线性阶 \(O(n)\)
  4. 线性对数阶 \(O(nlogn)\)
  5. 平方阶 \(O(n^2)\)
  6. 立方阶 \(O(n^3)\)
  7. K 次方阶 \(O(n^k)\)
  8. 指数阶 \(O(2^n)\)
  9. 阶乘阶 \(O(n!)\)
  10. 无穷阶 \(O(n^n)\)

时间复杂度分析

举例说明:

如果一个算法的运行时间固定的,也就是无论数据多大,运行时间都是一样的,那么这个算法的时间复杂度就是 \(O(1)\)。比如一个数组,长度为 \(n\),那么取出数组中的第一个元素,时间复杂度就是 \(O(1)\)

比如一个数组,长度为 \(n\),那么遍历这个数组,时间复杂度就是 \(O(n)\)。如果遍历两次,那么时间复杂度就是 \(O(2n)\),但是常数阶可以忽略,所以时间复杂度还是 \(O(n)\)。如果遍历两个数组,那么时间复杂度就是 \(O(n+m)\),也可以忽略常数阶,所以时间复杂度还是 \(O(n)\)

如果遍历一个二维数组,那么时间复杂度就是 \(O(n^2)\)。如果遍历一个三维数组,那么时间复杂度就是 \(O(n^3)\)。如果遍历一个 \(n\) 维数组,那么时间复杂度就是 \(O(n^n)\)

如果是一个二分查找算法,它的时间复杂度就是 \(O(logn)\)。之所以会出现对数,是因为每次查找都会把数组长度缩小一半,所以运行次数 \(k\) 满足 \(2^k=n\),所以 \(k=logn\)

空间复杂度分析

如果一个算法的内存占用是固定的,也就是无论数据多大,内存占用都是一样的,那么这个算法的空间复杂度就是 \(O(1)\)

如果一个算法的内存占用和数据规模成正比,那么这个算法的空间复杂度就是 \(O(n)\)。比如一个数组,长度为 \(n\),要求这个数组的前缀和,那么就需要一个长度为 \(n\) 的数组来存储前缀和,所以空间复杂度就是 \(O(n)\)

此外要注意的是空间复杂度在涉及到关于递归的算法时,要考虑到递归调用的栈空间,比如一个递归函数,每次递归都会调用自身,那么递归的次数就是 \(n\),所以空间复杂度就是 \(O(n)\)

在递归算法中,我们一般主要考虑时间复杂度,对于空间复杂度相比之下不是很关注。但在极端情况下仍然需要记得考虑这种情况。

posted on 2024-02-16 07:22  安逐悲  阅读(50)  评论(0)    收藏  举报

导航