算法的复杂度分为时间复杂度和空间复杂度。
时间复杂度是指衡量算法执行时间的长短;
空间复杂度是指衡量算法所需存储空间的大小。
定义:在进行算法分析时候,语句总的执行次数T(n)是关于问题规模n的函数,进而分型T(n)随着n的变化情况并确定T(n)的数量级.算法的时间复杂度,也就是算法的时间度量记作:T(n)=O(f(n)).它表示随着问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐近时间复杂度,简称时间复杂度.其中f(n)是问题规模n的某个函数.
简单来说T(n)代表时间频度:一个算法中语句执行次数称为时间频度
时间复杂度就是:算法的时间复杂度描述的是T(n)的变化规律,计作:T(n) = O(f(n))。
这里用大写的O( )来体现算法时间复杂度的记法,我们称之为大O记法.
分析一个函数或者算法的时间复杂度,其实就是 推导大O阶
推导大O阶:
1.用常数1取代运行时间中的所有加法常数.
2.在修改后的运行次数函数中,只保留最高阶项.
3.如果最高阶项存在且不是1,则去除与这个项相乘的常数.
得到的结果就是大O阶.
书上说把这个大O阶的推倒看做是一个游戏攻略一样 那我们就开始讲把~
1、【常数阶】
sum = 0, n = 100 #执行一次
sum = (1 + n) * n / 2 #执行一次
print(sum) #执行一次
这个算法的运行次数是f(n)=3,与n的大小无关
根据推导大O阶的方法,常数项3改为1,即时间复杂度为O(1)
对于分支结构(不含循环结构),无论真或假,执行的次数都是恒定的
不会随着n的变大而发生变化,其时间复杂度也是O(1)
2、【线性阶】
for i in range(n):
#这里是时间复杂度为O(1)的程序步骤序列
书上说我们分析算法的复杂度,关键就是要分析循环结构的运行情况
下面这是一个for循环,那么它的时间复杂度又是多少呢?首先循环体就是一个执行一次的循环体,总共执行了n次,那么执行次数就是f(n) =n,启动我们的游戏攻略三部曲知道,时间复杂度就是为O(n).
3、【对数阶】
#对数
count = 1
while(count < n):
count = count *2
对数阶不是很好理解
每次count都会乘以一个2,他会距离n更近一步
这里详细解释一下
count=1时 1
到2的x次方大于n的时候 循环就结束了
由2的x次方等于n --> x = logn,时间复杂度为O(logn)
4、【平方阶】
for i in range(n):
for j in range(n):
#这里是时间复杂度为O(1)的程序步骤序列
对应外层循环,不过是内部这个时间复杂度为O(n)的语句,在循环n次
所以这段代码的时间复杂度为O(n²)
当然为了说明我们的大O阶的推倒 再来一个for 循环
for i in range(n):
for j in range(i,n):
#这里是时间复杂度为O(1)的程序步骤序列
由于当i = 0时,内循环执行n此,当n = 1时, 执行了 n - 1 次, …当 i = n-1 时, 执行了1次,所以总的执行次数为:
n + (n -1) +( n -2 ) +… +1 = n(n +1)/2 = n^2/2 + n/2
根据我们的游戏秘籍的三部曲(保留最高阶,去除最高阶不是1的常数项),我们可以分析出来,时间复杂度为 O( n^2 );
最坏情况下的时间复杂度称最坏时间复杂度。一般不特别说明,讨论的时间复杂度均是最坏情况下的时间复杂度。 这样做的原因是:最坏情况下的时间复杂度是算法在任何输入实例上运行时间的上界,这就保证了算法的运行时间不会比任何更长。
算法的空间复杂度通过计算算法所需的存储空间实现,算法的空间复杂度的计算公式为: S(n) = O(f(n))。
通常没有特别指明时,复杂度指的是时间复杂度,我们写代码时,要学会以空间来换取时间。
总结:复杂度对我们开发过程中做算法以及项目的优化有着极大的帮助.虽然我们作为的是一个开发人员,不是一个科研人员,但是,我们了解时间和空间复杂度的概念和作用是有着很大的优势的。
AIMI-CN AI学习交流群【1015286623】获取更多AI笔记和资料,扫码加群:
分享技术,乐享生活:欢迎关注我们的公众号,每周推送AI系列资讯类文章,欢迎您的关注!