算法的时间复杂度
定义:在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,算法的时间复杂度,也就是算法的时间度量,记作:T(n)=O(f(n))。表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作时间复杂度,其中f(n)是问题规模n的某个函数。
用大写O( )来体现算法时间复杂度。
一般,T(n)增长最慢的算法称为最优算法。
常见的时间复杂度有这样几种:常数阶O(1)、线性阶O(n)、对数阶O(log2n) 、平方阶O(n2) 。
推导O( )方法:
1.用常数1取代运行时间中所有的加法常数;
2.在修改后的运行次数函数中,只保留最高阶项;
3.如果最高阶项存在且不是1,则去除与这个项相乘的常数;
得到的结果就是算法的时间复杂度。
1.常数阶O(1)
通常执行次数为1次,或者2、3……有比较明确的次数,这种时间复杂度认为是O(1)。
例如:
print("hello world")
或者:
a=1,b=3 #执行1次
c=a+b #执行1次
print(c) #执行1次
时间复杂度也是O(1)。
或者:
sum=0 #执行1次
a=1,n=100 #执行1次
sum=(1+n)*n/2 #执行1次
print(sum) #执行1次
这种虽然看起来带有n,但是我们执行起来只需要计算很少的次数(4次),与n无关,这种时间复杂度也是O(1)。
2.线性阶 O(n)
线性阶的循环结构复杂很多,要确定算法的阶次,常常要确定某个特定语句或某个语句集运行的次数,要分析算法的复杂度,关键是要分析循环结构的运行情况。
如:
sum=0
for i in range(0,n): #执行n次
sum=sum+i
print(sum) #执行1次
执行次数为(n+1),只保留最高阶项,即时间复杂度为O(n)。
3.对数阶O(log2n)
下面这段代码,时间复杂度应该是多少?
count=1
while count < n:
count = count * 2
每次count*2后,就距离n更近了,也就是说2x =n,得到x=log2n ,所以循环的时间复杂度为O(logn)。
4.平方阶O(n2)
关于循环嵌套,时间复杂度应该怎么计算?
如:
sum=0
for i in range(0,n): #执行n次
sum=sum+i
for j in range(0,n): #执行n次
sum=sum+j
print(sum) #执行1次
则总的执行次数为n*n+1=n2 +1 。时间复杂度为O(n2)。
或者:
sum1=0
sum2=0
for i in range(0,n): #执行n次
sum1=sum+i
for j in range(0,n): #执行n次
sum1=sum+j
for k in range(0,n):
sum2=sum+k
print(sum1,sum2) #执行1次
则总的执行次数为n*(n+n)+1=2n2 +1 。按照规则去掉常数项和高次项前面的系数,则时间复杂度为O(n2)。
更复杂的,循环多层嵌套,在算法执行起来效率很低,一般会尽量避免。