【问题标题】:Running time of for loopfor循环的运行时间
【发布时间】:2012-09-12 23:15:18
【问题描述】:

我似乎理解了更简单循环的基本概念......第一个循环在 O(n) 中运行,内部循环也是如此。因为它们都是嵌套的,所以乘以得到 O(n^2) 的总运行时间。

sum = 0; 
for ( i = 0; i < n; i++ ) 
  for j = 0; j < n; j++ ) 
    ++sum; 

虽然当事情开始发生转变时,我完全不知道如何解决这个问题。有人可以向我解释如何计算以下两项的运行时间吗?此外,任何可以进一步帮助我改进的易于理解的参考资料的链接也值得赞赏。谢谢!

sum = 0; 
for( i = 0; i < n; i += 2 ) 
  for( j = 0; j < n; j++ ) 
    ++sum; 

我能从中收集到的唯一信息是内循环在 O(n) 中运行。 i+=2 真的让我陷入了外循环。

sum = 0; 
for( i = 1; i < n; i *= 2 ) 
  for( j = 0; j < n; j++ ) 
    ++sum; 

根据我的尝试...外循环是 O(log(n)),内循环是 O(n),所以总是 O(n log(n))?

【问题讨论】:

  • 提示:+= 2 表示它的迭代次数是 ++ 的一半。
  • 所以这意味着外循环运行时间为 O(n/2)?
  • 是的,外部循环需要 n/2,但请记住,我们对非常大量的 n 感兴趣,所以就像 2n 会变成 O(n) n/2 会变成 O(n)。
  • 哦,对了!常量被丢弃。所以外部 O(n) 和内部 O(n) 的总运行时间为 O(n^2),对吗?

标签: performance big-o


【解决方案1】:

考虑 Big-O 性能的一个好方法是假设代码的每个元素都是一个数学函数,它接受 n 项并返回对这些项执行的计算次数。

例如,像for ( i = 0; i &lt; n; i++ ) 这样的单个for 循环将等效于函数i(),其中i(n) = n,表示对每个输入n 执行一次计算。

如果你有两个嵌套循环,那么功能等价于

for ( i = 0; i < n; i++ ) 
   for j = 0; j < n; j++ ) 

看起来像这两个函数:

i(n) = n * j(n)
j(n) = n

处理这两个函数会产生n*n = n^2 的最终结果,因为j(n) 可以替换n

这意味着,只要您能够解决任何单个循环的 Big-O,您就可以将这些解决方案应用于一组嵌套循环。

例如,让我们看看你的第二个问题:

for( i = 0; i < n; i += 2 ) 
  for( j = 0; j < n; j++ ) 

i+=2 表示对于n 项目(n0, n1, n2, n3, n4) 的输入集,您只触及该集的所有其他元素。假设你初始化了i=0,这意味着你只接触了(n0,n2,n4)的集合。这意味着您将用于处理的数据集的大小减半,并且意味着功能等价物的结果如下:

i(n) = (n/2) * j(n)
j(n) = n

解决这些问题可以得到(n/2) * n = (n^2)*(1/2)。由于这是 Big-O 工作,我们删除常量以生成 (n^2) 的 Big-O 值。

这里要记住的两个关键点:

  1. Big-O 数学从一组 n 数据元素开始。如果您试图确定循环通过该组 n 元素的 for 循环的 Big-O,那么您的第一步是查看增量器如何更改 for 例程的数据元素数量实际接触。

  2. Big-O 数学是 math。 如果您可以单独解决每个 for 表达式,您可以使用这些解决方案来构建您的最终答案,就像您可以解决对于一组具有共同定义的方程。

【讨论】:

  • 谢谢。在我提出的最后一个问题中,我注意到外循环以 i=1 开始,而内循环以 j=0 开始。这会影响如何根据我在原帖中所说的确定运行时间吗?我想我的意思是如果外循环是 O(log(n)),j=0 会影响它是 O(n) 吗?
  • 我怀疑i=1 只是为了使i *= 2 有意义(不能建设性地乘以零)。但是,好问题。请记住,O() 消除了常量,因为我们正在查看与数据集大小成正比的计算。从n1 开始意味着i 仅适用于集合的n-1 元素...而-1 是一个常量值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-07
  • 2011-07-10
  • 1970-01-01
  • 2011-11-14
  • 2019-02-09
  • 1970-01-01
相关资源
最近更新 更多