用Big-Oh表示法分析代码片段的运行时间

时间:2014-09-01 22:07:48

标签: algorithm big-o code-analysis

sum = 0; 'O(1)
for(i=1;i<2*n;i++) 'O(2n-1)
    for(j=1;j<i*i;j++) 'O((2n-1)^2 - 1)
        for(k=1;k<j;k++) 'O((2n-1)^2 - 1 - 1)
            if (j % i == 1) 'O(1)
                sum++;

当我添加并简化所有内容时,我得到O(n ^ 2)。解决方案说O(n ^ 4)。我做错了什么?

2 个答案:

答案 0 :(得分:1)

对于嵌套循环,您应该应用乘法规则而不是添加规则;对于单独的任务,您应该应用添加规则

你可以用这种方式思考问题:你被赋予了N个任务,而且每个任务都有O(M)的复杂性,总的复杂性是多少?我们有两种解释方法,一种使用加法规则,另一种使用乘法规则。

让我们先看看加法规则。为了得到答案,我们需要将所有这些N任务的复杂性加起来,因为它们都是独立的,N * O(M),相当于O(N) * O(M) = O(NM)

另一种解释是:遍历所有需要O(N)的任务,每项任务都需要O(M),因此O(N) * O(M) = O(NM)

请记住,大O符号表示复杂性的上限,因为O(N^5)O(N^4)更宽松,所以它在概念上是正确的,但是不受理。为什么我们会遇到这种情况?这是因为第三个循环已经松动了太多。第三个循环的实际复杂度为O(j)j的上限为(2n-1)^2 - 2。但是,如果您只是将O((2n-1)^2 - 2)作为第三个循环的复杂度并将其与之前相乘,则将其解释为 K的每个循环都具有(2n-1)^ 2的复杂度。 ,这不是真的。

答案 1 :(得分:0)

作为其他答案的补充,更加分析/肮脏(和硬)的方法是计算:

enter image description here

您可以在Mathematica(或在WolframAlpha在线)中将其计算为:

Sum[Sum[Sum[1, {k, 1, j - 1}], {j, 1, i^2-1}], {i, 1, 2*n-1}]

结果是5次多项式。

此时,检查结果也很有用。

可以使用有限微积分手工完成(对于这个主题你可以看到Knuth's book)。