网上都搜不到比较汇总的资料,打算自己总结一下。
在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化情况并确定T(n)的数量级。算法的时间复杂度,也就是算法的时间量度,记作:T(n)= O(f(n))。它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐近时间复杂度,简称为时间复杂度,是一种“渐进表示法”。其中f(n)是问题规模n的某个函数。用大写O()来体现算法时间复杂度的记法,我们称之为大O记法。一般情况下,随着输入规模n的增大,T(n)增长最慢的算法为最优算法。除此之外,其实还有平均情况复杂度、最好时间复杂度、最坏时间复杂度。。。一般没有特殊说明的情况下,都是指最坏时间复杂度。
1.1 分析一个算法的时间复杂度步骤:
- 用常数1取代运行时间中的所有加法常数。
- 在修改后的运行次数函数中,只保留最高阶项。
- 如果最高阶项存在且不是1,则去除与这个项相乘的常数。
- 得到的最后结果就是大O阶。
1.2
①常数阶 :常数加法 时间复杂度为O(1)。
②线性阶:一般含有非嵌套循环涉及线性阶,线性阶就是随着问题规模n的扩大,对应计算次数呈直线增长,循环的时间复杂度为O(n),因为循环体中的代码需要执行n次。
③平方阶 外层循环每执行一次,内层循环就执行N次,那总共程序想要从这两个循环出来,需要执行M*N次,时间复杂度为O(NM).
④对数阶
int i = 1, n = 100;
while( i < n )
{
i = i * 2;
}
由于每次i*2之后,就距离n更近一步,假设有x个2相乘后大于或等于n,则会退出循环。
于是由2^x = n得到x = log(2)n,所以这个循环的时间复杂度为O(logn)。
⑤线性对数阶:$O(nlogn) $,就是将时间复杂度为对数阶$O(logn)$的代码循环n遍的话,那么它的时间复杂度就是 n * O(logN)
⑥k次方阶 : $O(n^k)$,表示一个算法的性能会随着输入数据的每次增加而增大两倍,典型的方法就是裴波那契数列的递归计算实现。
⑦指数阶: $O(2^n)$,表示一个算法的性能会随着输入数据的每次增加而增大两倍,典型的方法就是裴波那契数列的递归计算实现。
1.3
评估算法的时间复杂度,用户需要遵循以下步骤:
1. 确定基本操作:首先,需要确定算法中执行时间最长的基本操作,通常是循环或递归中的一段代码。
2. 估算语句频度:估算每个基本操作的语句频度,即该操作在算法中被执行的次数。通常使用输入规模n来估算语句频度,例如n次循环操作或递归内部调用次数。
3. 求出时间复杂度:根据基本操作的语句频度,计算算法的时间复杂度。通常使用大O符号来表示时间复杂度,例如O(n)、O(nlogn)和O(n²)等。
4. 分析复杂度:分析算法的时间复杂度,并总结出算法的时间复杂度的特点、瓶颈等。
需要注意的是,通过理论分析算法时间复杂度并不一定能够准确反映出实际执行效率,实际执行效率还可能受到算法的实现方式、硬件环境、数据结构等因素的影响,因此,在实际应用中需要综合考虑这些因素。
2.1
常用的时间复杂度所耗费的时间从小到大依次是:
O(1) < O(logn) < (n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)
3.1 常见算法时间复杂度表
① 排序算法
常见排序算法时间复杂度表
② FFT 时间复杂度
一维离散傅里叶变换(DFT) 的时间复杂度是O(N*N);
一维FFT的时间复杂度为O(N*logN),其中N表示数据长度;
对于一个M*N的二维数据,FFT的时间复杂度为O( M*N*log(M*N) )
③ 滤波算法时间复杂度
卡尔曼滤波: O(n^3), n为状态向量的维度;
中值滤波:O(n^2logn), n为窗口的大小,拆分后的中值滤波时间复杂度为:O(nmlogn),
————————————————
参考链接:
https://blog.youkuaiyun.com/qq_17534301/article/details/82872357
百度安全验证https://baijiahao.baidu.com/s?id=1662190834355918541&wfr=spider&for=pc