我最近开始使用this普林斯顿课程的算法,我观察了以下模式
O(N)
double max = a[0];
for (int i = 1; i < N; i++)
if (a[i] > max) max = a[i];
O(N ^ 2)
for (int i = 0; i < N; i++)
for (int j = i+1; j < N; j++)
if (a[i] + a[j] == 0)
cnt++;
O(N ^ 3)
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)
cnt++;
这里的常见模式是随着循环中的嵌套增长,指数也会增加。 如果我有20-for循环,我的复杂性将是0(N ^ 20)?
,这是安全的吗?PS:请注意,20只是我选择的一个随机数,如果您在代码中嵌套20 for循环,那么显然您有问题。
答案 0 :(得分:6)
这取决于循环的作用。例如,如果我将第二个循环的结束更改为仅执行3次迭代:
for (int i = 0; i < N; i++)
for (int j = i; j < i+3; j++)
if (a[i] + a[j] == 0)
cnt++;
我们回到O(N)
关键是循环中的迭代次数是否与N有关,并且与N一样线性增加。
这是第二个循环进入N ^ 2的另一个例子:
for (int i = 0; i < N; i++)
for (int j = i; j < N*N; j++)
if (a[i] + a[j] == 0)
cnt++;
这将是o(N ^ 3)
答案 1 :(得分:2)
是的,如果循环的长度与N
成正比,并且循环如您所描述的那样彼此嵌套。
答案 2 :(得分:1)
在您的具体模式中,是的。但总的来说,假设是不安全的。无论所有封闭循环的状态如何,您都需要检查每个循环中的迭代次数是否为O(n)。只有在您确认是这种情况之后才能得出结论,复杂性为O(n loop-nesting-level )。
答案 3 :(得分:0)
是。即使你减少了迭代间隔,Big-o表示法随着N向无穷大的增加而变化,并且随着所有循环的长度与N成比例增长,这样的算法确实会有时间复杂度O(N ^ 20)
答案 4 :(得分:0)
我强烈建议您理解为什么每个循环从0到N的双重嵌套循环是O(N ^ 2)。使用求和来评估for循环中涉及的步骤数,然后删除常量并降低订购条款,您将获得该算法的Big-Oh。