时间复杂度衡量程序运行时间的多少;
空间复杂度衡量程序运行所需内存空间的大小。
时间复杂度
程序基本操作执行次数的四种场景:
1. 执行次数是线性:T(n) = n
2. 执行次数是对数:T(n) = logn
3. 执行次数是常数:T(n) = C,C= 1,2,3...
4. 执行次数是多项式:T(n) = n^2 + n
渐进时间复杂度(asymptotic time complexity):若存在函数 f(n),当 n 趋于无穷大时,T(n) / f(n)的极限值为不等于零的常数,则称 f(n) 是 T(n) 的同数量级函数,记 T(n) = O(f(n)),O(f(n)) 称为算法的渐进时间复杂度,简称时间复杂度。渐进时间复杂度用 O 表示,也称为大 O 表示法。
时间复杂度并不具体表示代码真正的执行时间,表示代码执行时间随数据规模增长的变化趋势。
循环次数最多原则,只需关注循环次数最多的那段代码即可。
加法原则,多段代码中,量级最大的那段代码时间复杂度=总的时间复杂度
嵌套代码的复杂度等于嵌套内外代码复杂度的乘积
时间复杂度将时间规模函数 T(n) 简化为数量级,如 n, n^2, n^3等。
由此得到三个原则:
-
如果运行时间是常数量级,用常数 1 表示;
-
只保留时间函数中的最高阶项;
-
如果最高阶项存在,则省去最高阶项前面的系数。
对应上面的四个场景:
1. T(n) = n,时间复杂度为 O(n),n是变量,如:for i in range(n)
2. T(n) = logn,时间复杂度为 O(logn)
3. T(n) = C,时间复杂度为 O(1),常量级复杂度代码,如:for i in range(10)
4. T(n) = n^2 + n,时间复杂度为 O(n^2)
时间消耗排序:O(1)< O(logn)< O(n)< O(n^2)
指数阶时间复杂度:O(2^n),随数据增加而增大两倍,如:裴波那契数列的递归计算实现。
对数阶 O(logn) 时间复杂度:换底公式,log(a)b = log(c)b / log(c)a,(c)代表以c为底;
while中每次都将 i 乘以 2,每次 i 距离 n 就越来越近,直到 i 不小于 n 退出,假设循环次数为x,2 的 x 次方等于 n,即 2^x=n => x = log₂n,时间复杂度为 O(logn)。
线性对数阶 O(nlogn) ,将对数阶O(logn)的代码循环n遍,时间复杂度就是 n * O(logn)
空间复杂度
算法编写的程序,运行过程中需要占用大小不等的存储空间,例如:
- 程序代码本身所占用的存储空间;
- 程序中如果需要输入输出数据,也会占用一定的存储空间;
- 程序在运行过程中,可能还需要临时申请更多的存储空间。
程序自身所占用的存储空间取决于其包含的代码量,如要压缩存储空间,要在实现功能的同时编写足够短的代码。程序运行过程中输入输出的数据,由问题而定,即便所用算法不同,程序输入输出所占用的存储空间也是相近的。
对算法的空间复杂度影响最大的是程序运行过程中所申请的临时存储空间;不同的算法所编写出的程序,其运行时申请的临时存储空间通常会有较大不同。
如果程序所占用的存储空间和输入值无关,则该程序的空间复杂度就为 O(1);反之,则需要进一步判断它们之间的关系:
- 如果随着输入值 n 的增大,程序申请的临时空间成线性增长,则空间复杂度为 O(n) ;
- 如果随着输入值 n 的增大,程序申请的临时空间成 n^2 关系增长,则空间复杂度为 O(n2) ;
多数情况下,算法更注重时间复杂度的比较,而空间复杂度只要在一个合理的范围内就可以。
参考:
一套图 搞懂“时间复杂度”_12 26 25 的博客-CSDN博客_时间复杂度
https://www.cnblogs.com/lazyegg/p/12572421.html