本文记录了博主对算法复杂度分析,常见的几种复杂度,以及平均时间复杂度、最好/最坏时间复杂度的总结。
关于算法的复杂度,我们通常采用大O来进行表示,在此我们假设每行代码的执行时间都一样,为一个单位时间,然后在这个假设的基础上进行时间、空间复杂度的分析。先分析一下上面的代码,2-4行的时间复杂度为3,紧接着有两个for循环,第一个for循环的时间复杂度为n,同时第6行的时间复杂度也为n,而内部的for循环的时间复杂度为2*n*n。总的时间复杂度则为2*n*n + 2*n+3。因此,此算法的时间复杂度为O(2*n*n + 2*n+3)。在此关于复杂度分析,有三点需要注意的:
1、
1 int cal(int n) { 2 int sum = 0; 3 int i = 1; 4 int j = 1; 5 for (; i <= n; ++i) { 6 j = 1; 7 for (; j <= n; ++j) { 8 sum = sum + i * j; 9 } 10 } 11 }
int a = 0; int b = a; int i;
1 i=1; 2 while (i <= n) { 3 i = i * 2; 4 }
2的x次方 = n 可以得出 x = log2 n 因为在采用O标记表示时间复杂度的时候忽略系数,所以本段代码的时间复杂度为O(log n) ; 需要注意的是如果将第3行的 2 换成3, 时间复杂度依旧为O(log n), 由于对数的运算规则不同的底之间是可以相互转换的,log3n = log32 * log2n
1 i=1; 2 j=1; 3 while (i <= n) { 4 while(j <= n) 5 i = i * 2; 6 }
1 int cal(int m, int n) { 2 int sum_1 = 0; 3 int i = 1; 4 for (; i < m; ++i) { 5 sum_1 = sum_1 + i; 6 } 7 int sum_2 = 0; 8 int j = 1; 9 for (; j < n; ++j) { 10 sum_2 = sum_2 + j; 11 } 12 return sum_1 + sum_2; 13 }
1 int cal(int m, int n){ 2 int sum_2 = 0; 3 int j = 1, i = 1; 4 for (; j < n; ++j) { 5 for(; i<m; ++i) 6 sum_2 = sum_2 + j; 7 }
1 // n表示数组array的长度 2 int find(int[] array, int n, int x) { 3 int i = 0; 4 int pos = -1; 5 for (; i < n; ++i) { 6 if (array[i] == x) pos = i; 7 } 8 return pos; 9 }
最好情况时间复杂度就是,在最理想的情况下,执行这段代码的时间复杂度。以上述代码为例,该代码为find函数,查找某个数字在数组重点位置,最理想的情况就是我们查找的数字位数数组的第一个位置,时间复杂度为O(1)。
最坏时间复杂度就是,在最糟糕的情况下,执行这段代码的时间复杂度。还是以上述代码为例,最坏的情况就是,我们要查找到数不在数组中,需要遍历整个数组,这个时候算法的时间复杂度为O(n)。
平均时间复杂度就是考虑算法的每种情况下,将每种情况的执行时间累加起来,然后再除以所有可能发生的情况数,就可以得到需要遍历的元素个数的平均值。分析上面这个代码的平均时间复杂度,一共有n+1种情况(0~n-1找到或n未找到)我们可以发现该算法的平均时间复杂度为(1+2+……+n+n)/n+1 = n(n+3)/[2(n+1)] ,我们可以得到,平均复杂度为O(n)。
类似平均时间复杂度还有加权平均时间,将每个情况发生的概率统计进来。也就是概率论中的加权平均值,上面每种情况发生的概率为1/(1+n),在平均时间复杂度的基础上乘以1/(1+n),得到加权平均时间复杂度O(1)。
原文:https://www.cnblogs.com/Trevo/p/11983888.html