《数据结构系列_计算时间复杂度》

1.前言

本来接下来想更新线性表的,结果我的一个小伙伴面试的时候碰到了这个题目,就打算先梳理科普一下这块的内容。

2.计算时间复杂度是做什么的?有什么用

时间复杂性,又称时间复杂度,算法的时间复杂度是一个函数,它定性描述该算法的运行时间。这是一个代表算法输入值的字符串的长度的函数。时间复杂度常用大O符号表述,不包括这个函数的低阶项和首项系数。使用这种方式时,时间复杂度可被称为是渐近的。

答:官方的解释,因为受硬件环境和输入规模的影响,代码的绝对执行时间是无法估计的,但是可以估算代码的基本执行次数。所以简单理解,时间复杂度就是其实简单来讲,就是用来计算算法基本操作的执行次数,描述该算法运行的时间的。衡量代码的好坏重要的2个指标就是运行时间和占用空间。

3.计算代码的执行次数

明白了时间复杂度是个什么意思之后,先看两个列子。

No1.

  public static void main(String[] args) {

        System.out.println("Hello world"); // 执行1次
        System.out.println("Hello 数据结构"); // 执行1次
  }

那么上面这个方法需要执行 1+1=2 次运算。运算时间记作T(n) = 1

No2.

  for (int i = 0; i < n; i++) {// 执行n + 1 次

      System.out.println("Hello world"); // 执行n次
      System.out.println("Hello 数据结构"); // 执行n次
  }

一共执行了n +1 +n +n = 3n+1次,运算时间记作T(n) = 3n+1

时间复杂度常用大O符号表述,时间的增长速度可以用 f(n) 来描述记作: T(n) = O(f(n))。随着 输入大小n 的增大,算法执行时间的增长率和 f(n) 的增长率成正比,所以 f(n) 越小,算法的时间复杂度越低,算法的效率越高。


4.推导时间复杂度的原则

1.我们晓得:常数项对函数的时间增长速度的影响并不大,所以当T(n)=c(常数)时,我们说这个时间复杂度为O(1),当T(n)不等于一个常数时,我们是可以把常数项忽略不计

比如当T(n) = 8 时间复杂度记作O(1),当T(n)=n+8, 忽略常数项,时间复杂度记为O(n)

2.我们晓得:对于一个函数而言,它的阶数对它的变化影响是最大的,所以通常在计算时间复杂度的时候,我们只会保留最高项的阶数,忽略掉与它相乘的系数。

比如当T(n) = 8n²+3,忽略常数项,忽略最高项的系数,时间复杂度记作O(n²)

3.我们晓得:一个函数中,高次项对函数的变化影响是最大的,所以我们在计算时间复杂度的时候,通常忽略低次项,只保留最高项

比如当T(n) = 4n³+8n²+3,忽略常数项,忽略最高项的系数,只保留最高项,时间复杂度记作O(n³)

这个又叫做大O推导法
总结就是

5.练一练

1.计算下面的时间复杂度

   for (int i = 0; i < n; i++) {// 执行n + 1 次

            System.out.println("Hello world"); // 执行n次
   }

时间复杂度为:T(n) = 2n+1,根据上面的规则,最后:T(n) = O(n)

2.计算下面的时间复杂度

for (int i = 0; i < n; i++) {// 执行n + 1 次
    for (int m = 0; m < n; m++) {// 执行n * n 次

        System.out.println("Hello world"); // 循环体时间复杂度为O(1)
    }
}

时间复杂度为T(n) = n×n×O(1) = O(n²)

3.计算下面的时间复杂度

 for (int k = 0; k < n; k++) {// 执行 n + 1 次

     System.out.println("Hello bmw"); // 循环体O(1)
 }

 for (int i = 0; i < n; i++) {// 执行n + 1 次
     for (int m = 0; m < n; m++) {// 执行n * n 次

         System.out.println("Hello Audi"); // 循环体O(1)
      }
 }

这个时间复杂度为多少尼?
第一个循环的时间复杂度为O(n),第二个双层循环的时间复杂度为O(n²),根据我们只保留最高项,这个函数的时间复杂度为T(n) = O(n²)。


4.计算下列时间复杂度

  if(true){
      for (int k = 0; k < n; k++) {// 执行 n + 1次

          System.out.println("Hello bmw"); // 循环体O(1)
      }
  }else {
      for (int i = 0; i < n; i++) {// 执行n + 1 次
          for (int m = 0; m < n; m++) {// 执行n * n 次

               System.out.println("Hello Audi"); // 循环体O(1)
           }
      }
  }

来算一下时间复杂度是多少?
这个的时间复杂度为T(n) = O(n), 第一个for循环的时间复杂性为T(n)=O(n) 第二个时间复杂度为T(n) = O(n²),对于条件判断语句,总的时间复杂度等于其中时间复杂度最大的路径的时间复杂度。但是if是true,else是不会执行的。


5.计算下列时间复杂度

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

先计算循环次数,
假如设定循环了x次,那么循环的条件就是2^x < n, 那么x = log(2)(n),所以T(n) = O(log(2)(n)) 即T(n) = O(log n)

6.思考题

   int function(int n) {

        if(n <= 1){
            return 1;
        }else {
            return n * function(n - 1);
        }
    }

来计算一下这个,知道的小伙伴可以底下留言。答案在下期博客

发布了30 篇原创文章 · 获赞 78 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/u010302765/article/details/89883317