我们如何定义一个程序的运行时间?为了排除“不同计算机”的运行速度对时间的影响,我们将一个程序的运行时间定义为“一个固定计算模型上单位操作的次数”,这个固定的计算模型一般指图灵机。
程序的运行时间与输入规模有关,也与程序采用的算法有关。同样规模的输入,由于其数据可能具有不同的“性质”,也会导致程序运行的时间有所不同。因此,我们用时间复杂度的概念来描述程序对于输入规模(比如n)在最坏情况下的运行时间。
我们关心复杂度的级别而不是复杂度的细节,因此我们引入高阶无穷大中的记号:
如果T(n),g(n)在n→∞时有T(n)g(n)≤C(有上界),就记T(n)=O(g(n))。其中g(n)是我们的一个标尺,对于多项式可以取n,n2⋯。如果取g(n)=n2,那么形如T(n)=n2,2n2,5n2+7n+9,n,2n+3,1的复杂度都可以被记为T(n)=O(n2),意思是T(n)不会超过g(n)这个级别,T(n)=n3就不满足T(n)=O(n2)。总之,O(g(n))≤C⋅g(n)。
如果T(n),g(n)在n→∞时有T(n)g(n)≥C(有下界),就记T(n)=Ω(g(n))。如果取g(n)=n2,那么形如T(n)=n2,2n2,5n2+7n+9,n3,2n的复杂度都可以被记为T(n)=Ω(n2),意思是T(n)至少有g(n)这个级别,T(n)=n,1等就不满足T(n)=Ω(n2)。总之,Ω(g(n))≥C⋅g(n)。
如果又有T(n)=O(g(n)),T(n)=Ω(g(n)),那么就记T(n)=Θ(g(n))。如果取g(n)=n2,那么形如T(n)=n2,2n2,5n2+7n+9的复杂度都可以被记为T(n)=Θ(n2),意思是T(n)正好就是g(n)这个级别,T(n)=n,n3等都是不满足T(n)=Θ(n2)的。Θ是一种精确的描述。总之,C1⋅g(n)≤Θ(g(n))≤C2⋅g(n)。
举个例子来分析算法的时间复杂度:求n个数中的第k小。一种思路是,每次找最小然后删除,复杂度O(n2);一种思路是,先排序然后取第k个,复杂度O(nlogn)。有一个称为“中位数的中位数”的算法,首先把整个数组五个五个分组,求出每组的中位数,复杂度O(n);再求出这些中位数的中位数v,这是一个递归的问题,假设整个问题的时间复杂度为T(n),那么这一步耗费T(n5);把所有小于v的数放进集合L,所有大于v的数放进集合R,等于v的放进集合M,耗费O(n);此时我们发现,在这n5个中位数中,比v小的那些中位数所在的每个组里至少有三个比v小,比它大的也是如此。也就是说,至少有n2⋅35个数比v小,有n2⋅35个数比v大。因此有310n≤|L|,|R|≤710n。因此递归到L,R的复杂度不超过T(710n)。综上,算法的复杂度可以写成递归表达式:T(n)=T(n5)+T(7n10)+O(n)。我们把O(n)写作Cn的形式:T(n)=T(0.2n)+T(0.7n)+Cn,递归地展开,最终T的项会趋向0,而带有Cn的项形成了等比数列T(n)=Cn+0.9Cn+0.92Cn+⋯,因此T(n)≤10Cn,得到了T(n)=O(n)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
2018-11-06 [SCOI2010] 传送带