时间复杂度
定义: 描述算法的运行时间。
那么为什么会引入这个概念呢?这个有什么用?
看下面
遇到一个算法时我们一般会如何评估它的时间开销呢?看下图
那么通过上图,我们发现统计算法运算时间时 受外界因素影响太大了,而且事后统计对于某些情况明显不适用。那么总结一下,现在的问题就是:
1.能否排除与算法本身无关的外界因素?
2.能否事先估计?
那么接下来就要靠 时间复杂度来解决这些问题了。
所以他的用途:事先预估算法时间开销T(n) 与问题规模n的关系。
知道了时间复杂度的概念、用途后,接下来就要想 这东西怎么算?
接下来通过一个实例来解释:
首先默认认为执行一行代码的时间是相同的。基于这一点就可以计算上述算法的运算时间了,并得出以下输出:
(注意:main函数里面的语句并不算其内)
上面的时间开销就这样算出来了,但由此问题也来了,假如一个算法的时间开销表达式很复杂呢 。比如:T[n] = 3n^9 + n^8 + n^5 + ....
那么此时从表达式中就很难看出一个算法的优劣了
所以接下来就需要思考以下问题:
【问题1】【解】
针对问题1,给出解决办法(结论):可以只考虑阶数高的部分,且其系数可省。
加法法则:多项相加,只保留最高阶的项,且系数为1
乘法法则:多项相乘都保留
例1:
T3(n) = 3n^3 + 99999999 -> O(n^3)
例2:
T2(n) = n^3 + n^2log₂n = O(n^3) + O(n^2log₂n)
注意:此时这个表达式 涉及到一个问题 怎么比较 对数和常数的时间复杂度优先级
此处先给结论:
时间复杂度由小到大
”常对幂指阶“
那么为什么这么排,看下图:(纵坐标代表时间开销)
另外注意:O 表示“同阶”,同等数量级。
时间复杂度O(n) 为 时间开销T(n)的简化
当n->无穷时,T(n)/O(n) = k(常数)
--------------------------------
--------------------------------
【问题2】【解】
先回顾问题2说什么:
针对问题2,解决办法(结论)
结论1:顺序执行的代码只会影响常数项,可忽略
结论2:只需挑循环中的一个基本操作分析它的执行次数与n的关系即可。
结论3:如果多层嵌套循环,只关注最深层循环的循环次数。
看例题来理解
例3:
例4:
例5:
看例5,此时首先涉及到以下概念:
最坏时间复杂度:
最好时间复杂度:
平均时间复杂度: 考虑所有输入数据都等概率出现的情况。
另一个就是本体循环次数的计算,由于n在任意一个位置的概率的是一样的,所以计算循环次数的话,就相当于计算其均值,即期望。
(数学期望(mean)(或均值,亦简称期望)是试验中每次可能结果的概率乘以其结果的总和,是最基本的数学特征之一。它反映随机变量平均取值的大小。)
附:这里说一下我对期望的理解,期望和平均值最容易混淆,因为俩者都是求平均,而期望从其定义上看就是 加权平均。(“加权”是一个数学概念,这个词让我们先分开解释,“加”就是“乘以”的意思;“权”通俗的理解就是“系数”的意思,这个系数叫“权重”。所以“加权”的意思就是“乘以权重”,即“乘以系数”的意思。)
----------------
总结:
-----------------
对于“期望”在网上找了不少资料但还是感觉一知半解,在此请教各位大佬,帮忙解答一下,万分感谢。