本文记录了博主对算法复杂度分析,常见的几种复杂度,以及平均时间复杂度、最好/最坏时间复杂度的总结。
复杂度分析
关于算法的复杂度,我们通常采用大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 }
常见的几种复杂度
常量阶o(1)
int a = 0; int b = a; int i;
对数阶O(logn)
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
线性对数阶O(nlogn)
1 i=1;
2 j=1;
3 while (i <= n) {
4 while(j <= n)
5 i = i * 2;
6 }
O(m+n)
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 }
O(m*n)
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

