时间复杂度解析

  算法,作为一个programmer应该再清楚不过。一个算法的好坏是依靠什么标准 来评判的呢?那就是时间复杂度空间复杂度
今天就来探讨下时间复杂度,什么是时间复杂度呢?

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

直接这么看太过晦涩难以理解,我们可以拆分成各个知识小块来理解,然后再回头看就会恍然大悟。

时间频度

我们假设计算机运行一行基础代码需要执行一次运算。

int aFunc(void) {
    printf("Hello, World!\n");      //  需要执行 1 次
    return 0;       // 需要执行 1 次
    //总共是两次运算
}
int aFunc(int n) {
    for(int i = 0; i<n; i++) {         // 需要执行 (n + 1) 次,最后一次判断false也为一次
        printf("Hello, World!\n");      // 需要执行 n * 1 次
    }
    return 0;       // 需要执行 1 次
    //总共是 n + 1 + (n * 1) + 1 = 2n + 2次运算
}

时间频度相信大家都有所认识了。但是在相同代码中,不同输入值仍可能造成算法的运行时间不同,因此我们通常使用算法的最坏情况复杂度,记为T(n),定义为任何大小的输入n所需的最大时间频度。(这是只考虑一种算法中时间频度多的那种情况)

时间频度 T(n)的几种自然特性:
   线性:T(n) = 3n

void aFunc(int n){
	for(int i = 0,i < n,i++){
    System.out.println("hello world!");//  需要执行 1 * n 次
	System.out.println("hello world!");//  需要执行 1 * n 次
    System.out.println("hello world!");//  需要执行 1 * n 次
	}
	 //总共是(1 * n) + (1 * n) + (1 * n) = 3n次运算
}

   对数:T(n) = 2logn
   扩充知识点:对数函数

void aFunc(int n){
	for(int i = 0,i < n,i*=2){
	System.out.println("hello world!");//  需要执行 logn 次
    System.out.println("hello world!");//  需要执行 logn 次
	}
	//总共是logn + logn = 2logn次运算
}

  常数:T(n) = 1

void aFunc(int n){
		System.out.println("hello world!");//需要执行一次
}
//无论n是多少,程序都只执行一次

   多项式:T(n) = 0.5n² + 0.5n
   扩充知识点:等差数列

void aFunc(int n){
	for(int i = 0,i < n,i++){
    	for(int y = 0,y < i,y++){
      	 System.out.println("hello world!");//需要执行(1 + 2 + n-2 + n-1)次
   	 }
    	 System.out.println("hello world!");//需要执行n * 1次
	}
}
//总共是(1 + 2 + n-2 + n-1) + n = n(n + 1)/2 = 0.5n² + 0.5n次运算

相信现在大家应该对时间复杂度有所理解,但是别着急,我们继续往下看。

大O表示法

大O表示法:算法的时间复杂度通常用大O符号表述,定义为T[n] = O(f(n))。称函数T(n)以f(n)为界或者称T(n)受限于f(n)。 如果一个问题的规模是n,
解这一问题的某一算法所需要的时间为T(n)。T(n)称为这一算法的“时间复杂度”。当输入量n逐渐加大时,时间复杂度的极限情形称为算法的“渐近时间复
杂度”。         --------百度百科

  看到这是否有同学不理解了。我先举个例子:现在假设有一段代码的时间频度为T(n) = n + 2,又有某个辅助函数f(n) = n²,当n趋近于无穷大时,T(n) / f (n)的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),而O(f(n))则 为算法的渐进时间复杂度,简称时间复杂度。
  在各种不同算法中,若算法中语句执行次数为一个常数,则时间复杂度为O(1),另外,在时间频度不相同时,时间复杂度有可能相同,如T(n) = n + 2与T(n) = n + 4它们的频度不同,但时间复杂度相同,都为O(f(n))。

时间复杂度的计算

在明白了什么是时间复杂度之后,我们还需要了解如何计算时间复杂度。
   1、省略常数项

int aFunc(void) {
    printf("Hello, World!\n");      
    return 0;       
}
//T(n) = 2n 时间复杂度为 O(n)

   2、忽略低次项

//T(n) = n² + n 时间复杂度为 O(n²)

   3、只保留最高次项,同时忽略最高项的系数

void aFunc(int n){
	for(int i = 0,i < n,i++){
    	for(int y = 0,y < i,y++){
      	 System.out.println("hello world!");//需要执行(1 + 2 + n-2 + n-1)次
   	 }
    	 System.out.println("hello world!");//需要执行n * 1次
	}
}
//T(n) = 0.5n² + 0.5n 时间复杂度为 O(n²)

   总结:如果一个算法的执行次数是 T(n),那么只保留最高次项,同时忽略最高项的系数后得到函数 f(n),此时算法的时间复杂度就是 O(f(n))。无论是顺序执行的算法还是含有条件判断的算法,我们都按算法最坏情况复杂度来计算。如果涉及到函数调用,则需要把调用的函数一并按照上面的规则加进去来计算时间复杂度。
   大家可以自己尝试着来算一算自己写的算法的时间复杂度是多少,从而进一步的加深对时间复杂度的理解,也能有目的性的去设计自己的算法。

参考链接:
(数据结构)十分钟搞定时间复杂度(算法的时间复杂度)
一套图 搞懂“时间复杂度”
时间复杂度
大O表示法

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值