你的第一个例子是什么?
sum = 0 ;
for ( i = 0 ; i < n ; i++ ) --> n
for ( j = 1 ; j < n^3 ; j = 3*j ) --> O(log n)
sum++ ;
第二个循环将是logn,因为我们每次都将j乘以3的因子,所以顺序将是O(n logn),而不是n^4。
每个循环的大O计算都是正确的,但是如果你有一个循环内部的循环,你需要将计算结果相乘。
sum = 0 ;
for ( i = n ; i > 0; i = i/3 ) --> log n
for ( j = 0 ; j < n^3 ; j++ )--> n^3
sum++ ;
这里的第一个循环也是log n,因为你不断地除以3,所以将两个循环的顺序相乘,我们得到:
O(logn * n^3) = O(n^3 logn)
我们无法进一步缩小,因为没有常量可以去除。
只是要指出一个简单的误解,对于这种情况,通常如果我们有以下场景,我们可以像下面这样缩小。
O(n^3 + n^2) = O(n3)
然而,您的情况不是订单的加法,而是乘法,因此我们不能再次删除这里的
O(logn)
。
如何分析代码:
这是我分析代码的方法,让我们举一个例子。
for(i=0; i < n; i++)
for(j=0; j < n*2; j++)
for(k=0; k<n; k++)
for(l=0; l<n; l+=3)
for(m=0; m<n; m*=2)
首先,找到每个循环的大0:
for(i=0; i < n; i++) --> O(n)
for(j=0; j < n*2; j++) --> 2n = O(n)
for(k=0; k<n; k++) --> O(n)
for(l=0; l<n; l+=3) --> n/3 = O(n)
for(m=0; m<n; m*=2) --> O(log n)
将外部循环乘以内部循环:
for(i=0; i < n; i++) --> O(n) * O(n) = O(n^2)
for(j=0; j < n*2; j++) --> 2n = O(n)
for(k=0; k<n; k++) --> O(n) * O(n) * (log n) = O(n^2 (log n))
for(l=0; l<n; l+=3) --> n/3 = O(n)
for(m=0; m<n; m*=2) --> O(log n)
现在我们将外层循环的订单加起来,得到:
O(n^2) + O(n^2 log n) = O(n^2 + n^2 (logn))
然后我们降低阶数。在这种情况下,n^2 log n 的增长率大于 n^2,所以我们可以删除 n^2,因为 n^2 logn 已足以解释增长率。因此,最终我们得到:
O(n^2 (log n))
j = 3*j
和i = i/3
循环的复杂度是 O(n^3) 或 O(n^(1/3))。但这是错误的。在这两种情况下,它们的复杂度都是 O(log n)。 - David Knipe