为什么这个卡特彼勒算法O(n ^ 2)不是O(n ^ 3)?

时间:2017-03-30 14:51:34

标签: algorithm

有人可以解释为什么这个算法是O(n^2)?根据{{​​3}},它是O(n ^ 2)。 我认为它是O(n ^ 3)的原因是因为外部循环(对于x)运行n次,内部循环(对于y)运行n-1次,并且在最差< / strong>场景例如A = [8, 100, 101, 102, 103, 104, 105, 106, 107],while循环(对于z)将运行n-2次,因此整体O(n^3)

为了完整性,A是带有正元素的有序数组,三元组(x,y,z)是A[x] + A[y] > A[z]的三角形。查找可以从A构建的三角形。

        int TrianglesCount(int[] A)
        {
            int result = 0;
            for (int x = 0; x < A.Length; x++)
            {
                int z = x + 2;
                for (int y = x + 1; y < A.Length; y++)
                {
                    while (z < A.Length && A[x] + A[y] > A[z])
                        z++;
                    result += z - y - 1;
                }
            }
            return result;
        }

4 个答案:

答案 0 :(得分:3)

让我们仔细看看下面的代码片段

int z = x + 2;
for (int y = x + 1; y < A.Length; y++)
{
   while (z < A.Length && A[x] + A[y] > A[z])
      z++;
   result += z - y - 1;
}

for循环显然执行A.lenght - (x+1)次,即O(n)。但是,内部while循环总共执行A.length - (x+2)次,因为每次执行都会增加z的值,并且最多可以递增A.length - (x+2)次,直到while条件失败。同样,这最多只是O(n)。因此,此代码段的总时间复杂度可以由O(n) + O(n) = O(n)限制。

由于针对O(n)的每个x值运行了代码段,因此整体时间复杂度为O(n^2)

KMP algorithm中使用类似的想法进行字符串匹配。

答案 1 :(得分:2)

您应该注意z在x-loop内初始化,而不是y-loop。并且在每次x迭代z可以增加最多A.length - x - 2次。

答案 2 :(得分:0)

诀窍在于z增加in total直到A.Length: 例如。如果我们在第一次迭代中感到不幸:

  • x = 0,y = 1,我们得到z从2到A.Length,在随后的y循环中,z根本不会递增。

答案 3 :(得分:0)

以下是我对此的解释。

首先,当n很小时,你不能谈论复杂性。复杂性的定义本身表明,当n倾向于无穷大时,复杂性只是“意味着什么”。例如,具有3个元素的数组上的冒泡排序可能看起来像O(n)。

从这个等式中取出,这是关于你的算法:

变量z在x循环内声明,而不是y循环,因此每次y循环完成时z都不会重新初始化。这意味着在x循环的每次传递中z将仅增加到A.length。一旦z达到A.length,它将不再增加,因此它不依赖于y循环。我希望这个解释是充分的,现在这个问题对你来说更清楚了。