我是时间复杂的新手,但我似乎不明白最后得到这个的背后逻辑:
100 (n(n+1) / 2)
此功能:
function a() {
int i,j,k,n;
for(i=1; i<=n; i++) {
for(j=1; j<=i; j++) {
for(k=1; k<=100; k++) {
print("hello");
}
}
}
}
这是我对算法的理解:
i = 1, 2, 3, 4...n
j = 1, 2, 3, 4...(dependent to i, which can be 'n')
k = 1(100), 2(100), 3(100), 4(100)...n(100)
= 100 [1, 2, 3, 4.....]
如果我将在上面使用此算法来模拟结束方程,则会得到以下结果:
结束方程式:
100 (n(n+1) / 2)
模拟
i = 1, 2, 3, 4... n
j = 1, 2, 3, 4... n
k = 100, 300, 600, 10000
我通常在youtube上研究这些内容,并了解Big O,Omega和Theta的想法,但是当涉及到这一点时,我不知道它们如何以方程式结束,例如我给出的方程式。请提供帮助,如果您有一些最佳做法,请分享。
编辑: 至于我自己对答案的假设,它认为应该是这样的:
100 ((n+n)/2) or 100 (2n / 2)
来源:
https://www.youtube.com/watch?v=FEnwM-iDb2g
At around: 15:21
答案 0 :(得分:2)
我认为您已经正确设置了i
和j
,只是不清楚为什么您说k = 100, 200, 300...
在每个循环中,k
从{{1}开始运行}到1
。
让我们首先考虑一下内部循环:
100
内部循环为 O(100)= O(1) ,因为其运行时不依赖于 k from 1 to 100:
// Do something
。现在,我们分析外部循环:
n
现在让我们计算i from 1 to n:
j from 1 to i:
// Do inner stuff
的执行次数:
Do inner stuff
这是我们经典的triangular sum i = 1 1 time
i = 2 2 times
i = 3 3 times
... ...
i = n n times
。因此,外部两个循环的时间复杂度为 O(n(n + 1)/ 2) ,可降低为 O(n ^ 2 ) 。
整个事情的时间复杂度是 O(1 * n ^ 2)= O(n ^ 2) ,因为嵌套循环会增加复杂度(假设运行时内部循环的变量独立于外部循环中的变量)。请注意,如果我们没有在各个阶段进行缩减,则将剩下 O(100(n)(n + 1)/ 2) O(n ^ 2) ,因为big-O表示法的属性。
一些提示: 您要求一些最佳实践。这是我用来分析您发布的示例的一些“规则”。
对于运行时彼此独立的嵌套循环,只需增加复杂度即可。将 O(1) 循环嵌套在外部 O(N ^ 2) 循环内部会导致 O(N ^ 2) 代码。
更多简化规则:http://courses.washington.edu/css162/rnash/quarters/current/labs/bigOLab/lab9.htm
如果您可以将代码分解为较小的部分(以我们与外部循环分开分析1 + 2 + 3 + ... n = n(n+1) / 2
循环的相同方式),则可以利用嵌套规则来找到组合的复杂度。
有关Omega / Theta的说明:
Theta是时间复杂度的“精确界限”,而Big-O和Omega分别是上限和下限。因为没有随机数据(类似于排序算法中的数据),所以我们可以获得时间复杂度的精确界限,并且上限等于下限。因此,在这种情况下使用O,Omega或Theta并没有什么区别。