O(nlogn) 的时间复杂度就相当于上面说到的“乘法法则”:一段代码的时间复杂度为O(logn) ,这段代码循环 n 次,时间复杂度就是 O(nlogn) 了。
O(m+n)、O(m*n)
这种情况下,代码的复杂度是由两个数据规模决定的。如下代码所示:
intcal(int m, int n){ int sum_1 = 0; int i = 1; for (; i < m; ++i) { sum_1 = sum_1 + i; }
int sum_2 = 0; int j = 1; for (; j < n; ++j) { sum_2 = sum_2 + j; }
return sum_1 + sum_2; }
从这段代码中可以看出m 和 n 是两个数据规模,无法评估 m 和 n 的量级大小。因此,不能省略其中任何一个,所以就是 O(m+n) 了。
O(2^n)、O(n!)
在上述表格中列出的复杂度量级,可以粗略的分为两类:多项式量级和非多项式量级。其中非多项式量级只有这两个。非多项式量级的算法问题也叫做 NP(Non-Deterministic Ploynomial,非确定多项式)问题。当 n 越来越大时,非多项式量级算法的执行时间会急剧增加,求解问题的执行时间也会无限增长,所以是种很低效的算法。
3.2. 最好、最坏情况时间复杂度
比如下面这段代码中,是在数组中查找一个数据,但是并不是把整个数组都遍历一遍,因为有可能中途找到了就可以提前退出循环。那么,最好的情况是如果数组中第一个元素正好是要查找的变量 x ,时间复杂度就是 O(1)。最坏的情况是遍历了整个数组都没有找到想要的 x,那么时间复杂就成了 O(n)。因此 O(1) 就是这段代码的最好情况时间复杂度,也就是在最好的情况下,执行这段代码的时间复杂度。O(n) 就是这段代码的最坏情况时间复杂度。
// n表示数组array的长度 intfind(int[] array, int n, int x){ int i = 0; int pos = -1; for (; i < n; ++i) { if (array[i] == x) { pos = i; break; } } return pos; }
3.3. 平均情况时间复杂度(加权平均时间复杂度或者期望时间复杂度)
最好和最坏情况时间复杂度都是极端情况发生的时间复杂度,并不常见。因此可以使用平均情况时间复杂度来表示。比如上面这段代码中查找 x 在数组中的位置有两种情况,一种是在数组中,另一种是不在数组中。在数组中又可以在数组中的 0~n-1 位置。假设在数组中和不在数组中的概率分别为 1/2,在数组中的 0~n-1 的位置概率都一样,为 1/(2 *n)。因此,上述这段的平均情况时间复杂度(或者叫加权平均时间复杂度、期望时间复杂度)为
voidinsert(int val){ if (count == array.length) { int sum = 0; for (int i = 0; i < array.length; ++i) { sum = sum + array[i]; } array[0] = sum; count = 1; }
array[count] = val; ++count; }
这段代码想要实现的就是往一个数组中插入数据,如果数组满了的话,那么就求和之后的 sum 放到数组的第一个位置,之后继续将数据插入到数组中。通过分析可以发现,这段代码的最好情况时间复杂度是 O(1),最坏情况时间复杂度是 O(n),平均时间复杂度是 O(1)。
Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。