首页 » 算法 » Big O 分析算法时间复杂度

big o是算法分析的常用手段,简单的说就是估计算法的执行时间,我们假设每行代码的时间是一样的,所以就可以理解为代码的执行次数.用n表示数据规模,f(n)表示执行次数,那么执行时间T(n) = O(f(n))表示Tn和执行次数fn成正比

1.看个简单的例子,1+ 1 + n + n ,即时间复杂度 (2n+2)*unit_time



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

2.再看一个例子,T(n) = O(2n2+2n+3),即O表示随着n变化时间的趋势的法则,对于函数的概念,可以理解为映射,这里大O表示次数和时间的映射

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

3.总结+ 计算手段(下面列的都是): * 大 O 时间复杂度实际上并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势,所以,也叫作渐进时间复杂度(asymptotic time complexity),简称时间复杂度

  • 计算手段1:只关注循环执行次数最多的一段代码---我们通常会忽略掉公式中的常量、低阶、系数,只需要记录一个最大阶的量级就可以了
  • 计算手段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))).
  • 如下满足加法法则,即n方
int cal(int n) {
   int sum_1 = 0;//sum_1 是100次
   int p = 1;
   for (; p < 100; ++p) {
     sum_1 = sum_1 + p;
   }

   int sum_2 = 0;//sum_2是n次
   int q = 1;
   for (; q < n; ++q) {
     sum_2 = sum_2 + q;
   }

   int sum_3 = 0;//sum_3是n的平方
   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;
 }
  • 计算手段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)).

    • 如下满足乘法法则,即n方
int cal(int n) {
   int ret = 0;
   int i = 1;
   for (; i < n; ++i) {
     ret = ret + f(i);//n次
   }
 }

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

4.常见的算法复杂度,复杂度分为两类:多项式量级和非多项式量级.非多项式量级只有两个:O(2^n) 和 O(n!),我们把时间复杂度为非多项式量级的算法问题叫做NP问题

  • O(1) 常数级别的都归为O(1),比如下面的代码执行了3次,也是O(1),一般情况下,只要算法中不存在循环语句、递归语句,即使有成千上万行的代码,其时间复杂度也是Ο(1)。
int i = 8;
 int j = 6;
 int sum = i + j;
  • O(logn)---对数阶算法复杂度,可以简单的理解为一个数除以k(比如k是2,即log2N)多少次可以得到1,如下面的就是

    • 对于log2N,log3N和log10N都记作logN,。因为log3n 就等于 log32 * log2n 而log32是一个常数,所以可以忽略
 i=1;
 while (i <= n)  {
   i = i * 2;
 }
  • 线性阶O(N) O(M+N)
  • 线性对数阶 O(NlogN)
  • 平方阶 O(n^2) ,O(n^3) ...O(n^k)

5.对于空间复杂度,用的最多的是O(1),O(n),O(n^2)。相对简单,不做深入

添加新评论