一般三个嵌套循环的 O(n^3) 复杂度的数学推导
Posted
技术标签:
【中文标题】一般三个嵌套循环的 O(n^3) 复杂度的数学推导【英文标题】:Mathematical derivation of O(n^3) complexity for general three nested loops 【发布时间】:2016-07-29 02:07:42 【问题描述】:Time complexity of nested for-loop 通过对两个循环 O(n2) 复杂度求和进行数学推导。
我尝试了一个练习来推导以下三个嵌套循环的示例如何获得 O(n3)。
简单的三个嵌套循环。
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= n; k++)
print(i * k * j);
总和是 = (n + n + n + .... + n) + (n + n + n + ... + n) + ... + (n + n + n + ... + n)
= n^2 + n^2 + .... + n^2
n 次 n^2 = O(n^3)
三个嵌套循环从一开始就没有运行 n 次
for(int i = 1; i <= n; i++)
for(int j = i; j <= n; j++)
for(int k = j; k <= n; k++)
print(i *j * k)
上面是嵌套循环的一种很常见的形式,我相信总结如下
= (n + (n -1) + (n -2) + (n - 3) + ... + 1) + ((n -1) + (n - 2) + (n - 3) +... + 1) + ((n -2) + (n -3) + (n - 4) + ... + 1) + ... + ((n - (n -2)) + 1)
= n(n - 1) /2 + (n-1) (n -2) / 2 + (n-2)(n-3)/2 + .... + 1
= 从这里我有点不确定我的逻辑是否正确。我相信 上面的每一个都计算为一个最大值为 n2 的多项式,这就是我们关心的时间复杂度,上面的等式分解为。
= n^2 + n^2 + n^2 +... +n^2
= n 乘以 n^2 = O(n^3)。
我的假设正确吗?
三个嵌套循环未从末尾运行 n 次
for(int i = 1; i <= n; i++)
for(int j = 1; j <= i; j++)
for(int k = 1; k <= j; k++)
print(i *j * k)
如果上面是两个嵌套循环,则总和将是 1 + 2 + 3 + 4 + ... + n。但是,对于三个嵌套的事件,我推断它是
= 1 + (1 + 2) + (1 + 2 + 3) + (1 + 2 + 3) + (1 + 2 + 3 + .... + n)
从这里我不确定如何推导出 O(n^3) 或如何进一步简化上述求和。
【问题讨论】:
第一个循环的总和是n*n*n
,即O(n^3)
,第二个也是。省略幂运算符并没有给自己带来任何好处。
循环应该采用 (x = 0; x
我投票结束这个问题,因为这是数学而不是编程。
@Saad 现有的 cmets 足以解释否决票。没有 O(n3) 这样的东西。然而,有 O(n^3) 这样的事情。你有没有打算更正你的帖子?
您已经修复了一些问题。不是全部。问题仍不清楚。
【参考方案1】:
使用以下事实:
1+2+3+...+i =i*(i+1)/2
,上面的总结可以写成:
1*(1+1)/2 + 2*(2+1)/2 + ... + n*(n+1)/2
。
显然i*(i+1) > i^2
,因此:
1*(1+1)/2 + 2*(2+1)/2 + ... + n*(n+1)/2 > (1^2+...+ n^2)/2
,众所周知:
1^2+...+n^2 = n^3/3 + n^2/2 + n/6
(可以通过归纳证明)。
因此,原来的和S
大于:
n^3/6 + n^2/4 + n/12
,即O(n^3)
。
【讨论】:
如果有人好奇,确切的公式是 n^3/6 + n^2/2 + n/3。确定这一点的一种方法是进行多项式曲线拟合。 最简单的方法:wolframalpha.com/input/…以上是关于一般三个嵌套循环的 O(n^3) 复杂度的数学推导的主要内容,如果未能解决你的问题,请参考以下文章
为啥使用 2 个嵌套循环(O(n^2) 复杂度)解决两个和问题,在仅更改循环计数器逻辑时运行得更快?