以下代码的增长顺序是什么?我的猜测是,每个循环的增长是线性的,但if语句令我感到困惑。我如何将其与整个事物包括在一起。我非常感谢解释性答案,以便我能理解所涉及的过程。
int count = 0;
for (int i = 0; i < N; i++)
for (int j = i+1; j < N; j++)
for (int k = j+1; k < N; k++)
if(a[i] + a[j] + a[k] == 0)
count++;
答案 0 :(得分:3)
在尝试确定代码的复杂性时,有两件事可能会让人感到困惑。
并非所有循环都从0开始。第二个循环从i + 1
开始,第三个循环从j + 1
开始。这会影响复杂性吗?它不是。我们只考虑前两个循环。对于i = 0
,第二次运行N - 1
次,i = 1
运行N - 2
次,...,i = N - 1
运行0
次。添加所有这些:
0 + 1 + ... + N - 1 = N(N - 1) / 2 = O(N^2).
所以不从0开始不会影响复杂性(请记住,大哦忽略低阶项和常量)。因此,即使在此设置下,整个事情也是O(N^3)
。
if
声明。 if
语句显然与此无关,因为它只是最后一个循环的一部分,并且不包含break
语句或其他会影响循环的代码。它只会影响计数的增量,而不会影响任何循环的执行,因此我们可以安全地忽略它。即使计数没有递增(O(1)
操作),也会检查if
条件(也是O(1)
操作),因此无论有没有执行相同的大量操作if
。
因此,即使使用if
语句,算法仍为O(N^3)
。
答案 1 :(得分:2)
代码的增长顺序为O(N ^ 3)。
通常,长度为N的k个嵌套循环有助于O(N ^ k)的增长。
答案 2 :(得分:1)
这里有两个是发现时间复杂度是Theta(N ^ 3)而没有太多的计算。
首先,从0到N-1范围内选择i<j<k
。从N中选择3个对象的方法的数量是binomial coefficient N选择3 = N*(N-1)*(N-2)/(3*2*1) ~ (N^3)/6 = O(N^3)
,更准确地说是Theta(N ^ 3)。
其次,上限是您从N种可能性中选择i,j和k,因此最多只有N*N*N = N^3
个选项。这是O(N ^ 3)。您还可以找到相同类型的下限,因为您可以选择0从0到N / 3-1,j从N / 3到2N / 3-1,k从2N / 3到N-1。这为您提供至少地板(N / 3)^ 3选项,大约是N ^ 3/27。由于您具有相同形式的上限和下限,因此时间复杂度为Theta(N ^ 3)。