时间复杂度:
算法的运行时间。
什么是大O:
大O用来表示上界的。
数据规模:
在决定使用哪些算法的时候,不是时间复杂越低的越好(因为简化后的时间复杂度忽略了常数项等等),要考虑数据规模,如果数据规模很小甚至可以用O(n^2)的算法比O(n)的更合适(在有常数项的时候)。
就像上图中 O(5n^2) 和 O(100n) 在n为20之前, 很明显 ,
O(5n^2)是更优的,所花费的时间也是最少的。
那为什么在计算时间复杂度的时候要忽略常数项系数呢,也就说O(100n) 就是O(n)的时间复杂度,
O(5n^2) 就是
O(n^2)
的时间复杂度,而且要默认O(n) 优于O(n^2) 呢 ?
这里就又涉及到大O的定义,因为大O就是数据量级突破一个点且数据量级非常大的情况下所表现出的时间复杂度,这个数据量也就是常数项系数已经不起决定性作用的数据量。
所以我们说的时间复杂度都是省略常数项系数的,是因为一般情况下都是默认数据规模足够的大,基于这样的事实,给出的算法时间复杂的的一个排行如下所示:
复杂表达式的化简
1、去掉运行时间中的加法常数项 (因为常数项并不会因为n的增大而增加计算机的操作次数)。
2、去掉常数系数(上文中已经详细讲过为什么可以去掉常数项的原因)。
3、只保留最高项,去掉数量级小一级的n (因为n^2 的数据规模远大于n),最终简化为:
例如:
O(2*n^2 + 10*n + 1000)
去掉运行时间中的加法常数项:
O(2*n^2 + 10*n)
去掉常数系数:
O(n^2 + n)
去掉数量级小一级的n:
O(n^2)
如果这一步理解有困难,那也可以做提取n的操作,变成O(n(n+1)) ,省略加法常数项后也就别变成了:
O(n^2)
O(logn)中的log是以什么为底?
平时说这个算法的时间复杂度是logn的,那么一定是log 以2为底n的对数么?
其实不然,也可以是以10为底n的对数,也可以是以20为底n的对数,但我们统一说 logn,也就是忽略底数的描述。
为什么可以这么做呢?如下图所示:
假如有两个算法的时间复杂度,分别是log以2为底n的对数和log以10为底n的对数,那么这里如果还记得高中数学的话,应该不难理解以2为底n的对数 = 以2为底10的对数 * 以10为底n的对数
。
而以2为底10的对数是一个常数,在上文已经讲述了我们计算时间复杂度是忽略常数项系数的。
抽象一下就是在时间复杂度的计算过程中,log以i为底n的对数等于log 以j为底n的对数,所以忽略了i,直接说是logn。
这样就应该不难理解为什么忽略底数了。
算法超时:
来源链接: link