【问题标题】:Determining the time complexity for code segments [duplicate]确定代码段的时间复杂度
【发布时间】:2017-09-07 20:53:57
【问题描述】:

以下每个代码段的时间复杂度是多少?

1. int i, j, y=0, s=0;
for ( j = 1; j <= n; j ++) 
{
  y=y+j;
}
for ( i = 1; i <= y; i ++) 
{
  s++;
}

我的答案是 O(2n),因为它遍历每个循环 n 次并且有两个循环

2. function (n) {
  while (n > 1) {
  n = n/3 ;
}

我对此的回答是 n^(1/3),因为 n 每次都会变成它的三分之一

3. function (n) {
int i, j, k ;
for ( i = n/2; i <= n; i ++ ) {   //n/2?
  for ( j = 1; j <= n; j = 2*j ) {  //logn
    for ( k = 1; k <= n; k = 2*k ) {  //logn
      cout << ”COSC 2437.201, 301” << endl;
    }
  }
}
}  

我说这个问题的答案是 O(log2*log2n*n/2) 但我对第一个 for 循环感到很困惑。循环只需要迭代 n 次的一半,所以它是 n/2 正确的吗?谢谢大家的帮助。

【问题讨论】:

  • 首先,O(2n) 只是 O(n) - 这是问题 1 的错误答案。
  • 第一个 for 循环究竟是什么让你感到困惑?
  • 第一段怎么可能是 O(n) 之外的任何东西?对于第一个循环,循环只需要迭代 n 次的一半,所以它会是 n/2 正确吗?
  • 第二个循环呢?这取决于第一个循环后y 的值,对吧?那会是什么?
  • "n^(1/3) 因为 n 每次都变成它的三分之一" 不合逻辑。

标签: c++ algorithm time-complexity notation


【解决方案1】:

问题 1

第一个循环是O(n),因为它运行n 次。 然而,第二个循环执行y 次,而不是n - 所以总运行时间不是“2n

在第一个循环结束时,y 的值为:

因此第二个循环占主导地位,因为它是O(n^2),因此也是整体复杂度。


问题 3

这个答案是正确的(但同样,在 O 表示法中删除 2 的因子)。

但是,您必须小心不要天真地将循环的复杂性相乘,因为内部循环的边界可能取决于外部循环的自发值。


问题 2

不是O(n^(1/3))!你的推理是错误的。

如果仔细观察这个循环,它实际上类似于问题 3 中的内部循环的 reverse

  • 在第三季度,k 的值从 1 开始,每次乘以 2,直到达到 n
  • 在第二季度,n 的值每次除以 3,直到达到 1。

因此他们都采取O(log n) 步骤。

(顺便说一句,O(n^(1/3)) 循环看起来像这样:)

for (int i = 1; i*i*i <= n; i++)
   /* ... */

【讨论】:

  • 帮别人做作业是可以的,但不要为他们
  • @n.m.你是对的;我认为 OP 可能需要更多的解释,而不是挤进评论中
  • 我的意思是我不只是想得到答案。您的回答是唯一真正帮助我了解发生了什么的答案。谢谢。
猜你喜欢
  • 2021-10-23
  • 1970-01-01
  • 2022-01-27
  • 1970-01-01
  • 2013-11-18
  • 1970-01-01
  • 2018-07-01
  • 2020-07-24
  • 1970-01-01
相关资源
最近更新 更多