0-时间复杂度
本人作为一名大三学生,在大学前两年生涯中意识到自己时间的荒废,因此重新审视自己的水平,准备以我自己的视角重新学习算法和数据结构等计算机知识。特此在这里记录。
时间复杂度
在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化情况并确定T(n)的数量级。算法的时间也就是算法的时间量度,记作:T(n}=O(f(n))。它表示随问题规模n的增大,算法执行时间的增长率和 f(n)的增长率相同,称作算法的渐近时间复杂度,简称为时间复杂度。其中f(n)是问题范围为n的某个函数。
考虑以下伪码:
int n,sum=0;
for(int i=1;i<=n;i++){
sum+=i;
}
上述的代码表示计算从1到n的求和,其中建立变量共执行了一次(也就是构建变量),而for循环则执行了n+1次,在循环中的数执行了n次,也就是说该段代码时间复杂度为O(n).
//假设数是连续增长的
int n,a[1],a[n],sum;
sum=(a[1]+a[n])*(n/2);
上面的算法如果普适到n=100,a[1]=1,a[100]=100,那么就是高斯在课上提出的计算1-100=5050的算法,可以看出此时算法的时间复杂度为O(1),也就是常数时间,那也就是说高斯的加法求和是比上面for循环要更优的。
综上所述我们可以总结部分情况下的时间复杂度:
for(i=1;i<=n;i++) //O(n)
for(i=1;i<=n;i+=2) //O(n)
for(i=1;i<=n;i*=2) //O(lgn)
while(i){ //i很大
~~~
i--;
} //O(n)
f[n]=f[n-1]+1; //O(n)
f[n]=f[n/2]+1; //O(lgn)
根据前人的经验可以得到如下的时间复杂度关系:
事实上后三个就算我们实现了这种算法也很少使用,因为它的成本实在是太高了。
为了更好理解时间复杂度对我们平时做题带来的影响,我们举一个具体的例子:
让一个运行速度较快和一个运行速度较慢的及其处理1000万个数的数组,如果这个数是8字节的整数,那么输入的内存占用为80MB。假设A为较快那台机子,它每秒可以执行百亿条指令,而B只能运行1000万条指令,按照计算A应该比B快1000倍左右。然而当我让A计算\(O(2n^2)\)的指令,B只需计算\(O(50nlgn)\)的指令时,我们进行对比:
\(T_{A}=\frac{2*(10^7)}{10^{10}}=20000(s)\) \(T_{B}=\frac{50*10^7}{10^7}=1163(s)\)
可以看出即使A的运算速度比B要快得多,但是B具有更优秀的算法时计算大数据量的时间是要比A好的多的,因此选取一个正确的算法要远比一台优秀的计算机重要。

浙公网安备 33010602011771号