时间复杂度分析三个实用技巧

时间复杂度分析有三个实用技巧。
1.只关注循环次数最多的一段代码。
大O时间复杂度只是说明执行效率随着数据规模改变的变化趋势,通常会忽略系数、低阶项和常数项,这样的话,我们只需要分析执行次数最多的那一段代码就行。
使用下边代码来说明一下:

 int cal(int n) {
   int sum = 0;
   int i = 1;
   for (; i <= n; ++i) {
     sum = sum + i;
   }
   return sum;
 }

第2行和第3行运行时间都是常量,可以忽略。第4行和第5行执行次数都是n,合起来应该是2n,但是因为可以忽略前边的系数2,所以这段代码时间复杂度T(n)=O(n)。
2.加法法则:总复杂度等于量级最大的那段代码的复杂度
这里再用一段代码来分析一下:

int cal(int n) {
   int sum_1 = 0;
   int p = 1;
   for (; p < 100; ++p) {
     sum_1 = sum_1 + p;
   }

   int sum_2 = 0;
   int q = 1;
   for (; q < n; ++q) {
     sum_2 = sum_2 + q;
   }
 
   int sum_3 = 0;
   int i = 1;
   int j = 1;
   for (; i <= n; ++i) {
     j = 1; 
     for (; j <= n; ++j) {
       sum_3 = sum_3 +  i * j;
     }
   }
 
   return sum_1 + sum_2 + sum_3;
 }

这段代码分别求sum_1、sum_2和sum_3,接下来我们求出每一部分时间复杂度,然后把最大量级当成这段代码时间复杂度。
可以看出求sum_1那部分代码的时间复杂度T(n)=O(1),求sum_2那部分代码的时间复杂度T(n)=O(n),求sum_3那部分代码的时间复杂度T(n)=O(n^2),所以按照上边法则一:只关注循环次数最多的一段代码,故而这个函数总的时间复杂度T(n)=O(n^2)。也就是说,总的时间复杂度就等于量级最大的那段代码的时间复杂度。
抽象成公式就是:如果 T1(n)=O(f(n)),T2(n)=O(g(n));那么 T(n)=T1(n)+T2(n)=max(O(f(n)), O(g(n))) =O(max(f(n), g(n)))。
3. 乘法法则:嵌套代码的复杂度等于嵌套内外代码复杂度的乘积
类比上边的加法法则,就是:如果 T1(n)=O(f(n)),T2(n)=O(g(n));那么 T(n)=T1(n)*T2(n)=O(f(n))*O(g(n))=O(f(n)*g(n))。
也就是说若T1(n)=O(n),T2(n)=O(n^2),那么T(n)=T1(n)+T2(n)=O(n)*O(n^2)=O(n^3)。
落实到具体代码上就可以把乘法法则看成嵌套循环。
下边再用具体代码来举一下例子:

int cal(int n) {
   int ret = 0; 
   int i = 1;
   for (; i < n; ++i) {
     ret = ret + f(i);
   } 
 } 
 
 int f(int n) {
  int sum = 0;
  int i = 1;
  for (; i < n; ++i) {
    sum = sum + i;
  } 
  return sum;
 }

现在单独看 cal() 函数。假设 f() 只是一个普通的操作,那第 4~6 行的时间复杂度就是,T1(n) = O(n)。但 f() 函数本身不是一个简单的操作,它的时间复杂度是 T2(n) = O(n),所以,整个 cal() 函数的时间复杂度就是,T(n) = T1(n) * T2(n) = O(n*n) = O(n^2)。
——极客时间《数据结构与算法之美》学习笔记 Day 5

你可能感兴趣的:(数据结构和算法,算法,数据结构)