何谓『时间复杂度』 作为数学渣的我们怎么才能明白?

一直对算法的基础“时间复杂度” 的概念理解的不是很清楚,感觉摸棱两可,尤其遇到复杂的代码,分期时间复杂度简直就是一头雾水,现在腾出手来好好学习一下,将心得以及学习过程记录下来,供以后参考

1.名词解释:

    在计算机科学中,算法的时间复杂度(Time complexity)是一个函数,它定性描述该算法的运行时间。这是一个代表算法输入值的字符串的长度的函数。时间复杂度常用大O符号表述,不包括这个函数的低阶项和首项系数。使用这种方式时,时间复杂度可被称为是渐近的,亦即考察输入值大小趋近无穷时的情况。【来源于维基百科】

2.分析

首先,最重要的,我们都知道,算法的复杂度都是假设在最坏的情况下的运行耗费时间,并且假设每一句简单的代码的运行时间都是相同的。

public static void main(string args[]){
    int n = 100;
    for(int m = 0;m<n;m++){
        System.out.println("Hello World!");
    }
}

从总简单的循环输出Hello World来说,总共有如下几句:

蓝色框运行时间为2个时间单位;

黑色框运行时间为n+1个时间单位(因为判断了n+1次);

红色框运行时间为n+n=2n个时间单位;

那么总体来说,这段代码运行时间就是3n+3个时间单位。运行花费的时间和我们的n成正相关。我们可以取运行总时间为T(n),

那么T(n)=3n+3。

因为我们总考虑最坏的情况,那么当n为10000,百万,或者无穷大的时候,这个式子其实就和3没有关系了,3并不能改变n 的数量级,这个式子就可以简写为T(n)=n

大部分情况下,我们会保留最高次项并忽略该项的系数。

比如:                                                          

T(n)=n+1 忽略常数项 T(n)~n                   

T(n)=n+n^2 忽略低阶项 T(n)~n^2         

T(n)=3n 忽略最高阶的系数 T(n)~n   

忽略低阶项,简单的来说,就是忽略当n非常大的时候,一个项相对于另一个项而言,影响非常小的项。一般而言,我们记住;

O(1)<O(logN)<O(N)<O(NlogN)<O(n^2)<O(n^3)<O(1)<O(1)<O(1)<O(1)<O(1)<O(1)

话说回来,我们化简完函数后,这个式子就是程序算法的时间复杂度了,我们记为O(f(n)),f(n)就是简化后的式子,比如说刚开始我们说的T(n)=3n+3,简化后T(n)~f(n)=n,即O(n).

更准确地说O代表了运行时间函数的一个渐进上界,即T(n)在数量级上小于等于f(n)

所以时间复杂度就可以表示某个算法的运行时间的趋势,大致地度量算法效率的好坏。那我们该如何算这个时间复杂度呢?

首先,我们先得出运行时间的函数,类似于前面的3n+3,第二步就是对函数进行简化,类似于前文的得到T(n)=n。

  1. 用常数1来取代运行时间中所有的加法常数
  2. 在新的函数公式中只保留最高阶项
  3. 如果最高阶项存在且不是1,则忽略这个项的系数

举个栗子:

int n = 100;
n = n+1;
System.out.println(n)

三句代码,每一行执行一次,单次时间为1,那么T(n)=3,简化后为1,则时间复杂度为O(1).

如果一个算法代码太多,上面这样算就显得有点傻。大部分时候我们可以耍耍小聪明。一般来说,最内部执行次数最多的语句就能决定整个算法的时间复杂度了。

for(int i = 0;i<n;i++){
    System.out.println("HelloWorld");
}

如上的for循环,我们只需要关注最内层的语句执行次数的而规律就行了。很明显,这个print语句会随着问题规模n的增加会呈线性增加,与n正相关,则可以判定时间复杂度为O(n)。

for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
        System.out.println("Hello World")
    }
}

很明显,双层for循环的时间复杂度为O(n*n).

int sum = 1;
while(sum<n){
    sum = sum*2
}

这段代码的复杂度就厉害了,是对数级别的。每循环一次,sum就自乘2,什么时候跳出循环呢?不知道,假定为x,那么2^x=n,解出x=logn。这说明随着n的增大,最消耗时间的内层语句是呈对数变化的。

 

这么一讲是不是感觉简单了很多?此篇先告一段落。

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值