算法复杂度
算法复杂度分两种,时间复杂度和空间复杂度。分别代表了算法的用时,以及算法所占用的内存空间。复杂度越小,运行效率越高。
复杂度表示法
一般用大写字母 \(O\) 表示,称为大 \(O\) 表示法。比如 \(O(n)\),\(O(n^2)\) 等。这里的 \(n\) 代表了算法的输入规模,比如数组的长度,链表的长度等。\(n\) 和 \(n^2\) 表示了算法的复杂度,\(n\) 表示线性复杂度,\(n^2\) 表示平方复杂度。
复杂度分级
常见的复杂度,按照性能从高到低排序如下:
- 常数阶 \(O(1)\)
- 对数阶 \(O(logn)\)
- 线性阶 \(O(n)\)
- 线性对数阶 \(O(nlogn)\)
- 平方阶 \(O(n^2)\)
- 立方阶 \(O(n^3)\)
- K 次方阶 \(O(n^k)\)
- 指数阶 \(O(2^n)\)
- 阶乘阶 \(O(n!)\)
- 无穷阶 \(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)\)。
在递归算法中,我们一般主要考虑时间复杂度,对于空间复杂度相比之下不是很关注。但在极端情况下仍然需要记得考虑这种情况。
标签:遍历,复杂度,第一课,算法,时间,数组,就是 From: https://www.cnblogs.com/NayamiOR/p/18016885