我的老师声称此代码块将花费O(n)时间来执行。我试图找出原因。我意识到捆绑在一起的两个for循环将是一个算术序列.....我的逻辑方法是,如果K = 3,则内部循环将运行3次,然后运行两次,然后运行一次。如果K = 2,则内部循环将运行两次,一次,然后停止。
在数学上,对于k = 3,它应该是N,N-1,N-2
后来我可以使用算术级数公式,得到N *(N +(N-(N-1))/ 2 ..
我不知道该如何处理while循环。
我可以推测的是,当N = 4时,循环运行两次,直到N = 9时,循环运行三次...我将如何在数学上进行设置?
最终结果是N *(N +(N-(N-1)))/ 2 + O(while循环)以获得O(N)?
任何建议将不胜感激。
void doit(int n) {
int k = 0; int m = n; int s = 0;
while (m <= n) {
k = k + 1;
m = k * k;
}
for (int i = 0; i < k; i++) {
for (int j = i; j < k; j++) {
s = s + m;
m = m - 1;
}
}
}
答案 0 :(得分:5)
循环本身是O(k^2)
,但实际情况是循环之前。 while
循环会找到比m = k^2
大的最小平方数n
,因此基本上是因为m
与n
相关,最终结果实际上是{{1 }}。
答案 1 :(得分:1)
正如您所看到的,while循环和嵌套的for循环是相互独立的。因此,我们将分别计算每个时间的复杂度。
在while循环中,我们有独立于n
的指令。这里的问题是我们如何计算while循环运行的次数。如果我们稍微作弊并以k
而不是n
的角度来看,我们会注意到,一旦退出循环,k
将保持循环运行的次数对于。就像真的有柜台一样。此时k^2
大致等于n
,因此复杂度为O(sqrt(n))
真正的魔术在这里发生,因为这部分将证明O(n)
克服了while循环的O(sqrt(n))
复杂性。
每个for
循环所花费的时间可以看作是恒定数量的指令的总和。因此,我们将有一个嵌套的总和。我会尝试为您描述它,因为StackOverflow不会让我发布图片。您基本上有两个总和,一个以i=0
开始并上升到(k-1)
,另一个是从j=1
开始并上升到(k-1)
,并且您所加的都是一个常数命令数c
。
您可以轻松地计算出该总和,结果发现复杂度为O(k^2)
,但同样,我们必须考虑n
,就像它变成O(n)
一样。