【问题标题】:Time complexity of the java codejava代码的时间复杂度
【发布时间】:2012-08-12 19:42:52
【问题描述】:

我正在学习 coursera 上的算法课程,但我被困在这个特殊问题上。我应该找到这段代码的时间复杂度。

int sum = 0

 for (int i = 1; i <= N*N; i = i*2)

  {
     for (int j = 0; j < i; j++)
           sum++; 
  }

我在eclipse本身检查过,对于N的任何值,sum语句执行的次数都小于N

final value of sum:
for N=8 sum=3 
for N=16 sum=7 
for N=100000 sum=511

所以时间复杂度应该小于N 但是给出的答案是 N 的 2 次方,这怎么可能?

到目前为止我做了什么:

第一个循环将运行 log(N^2) 次,因此第二个循环将执行 1,2,3.. 2 logN

【问题讨论】:

  • 你为什么会有那个内循环?为什么不直接 sum += i?

标签: java algorithm time-complexity


【解决方案1】:

第一个内部循环将是 1 + 2 + 4 + 8 .. 2^M,其中 2^M 是

2 到 N * N 的幂的总和约为 2 * N * N 或 O(N ^ 2)

注意:当 N=100000 时,N*N 将溢出,因此其结果具有误导性。如果您认为溢出是问题的一部分,那么对于大数来说,总和是相当随机的,因此您可以争论它的 O(1),即如果 N=2^15,N^2 = 2^30,总和将为整数.MAX_VALUE。没有更高的 N 值会产生更高的总和。

【讨论】:

  • 尝试优化器,看看它是 O(1)
  • 如何 1 + 2 + 4 + 8 .. 2^M (N^2) 请解释一下
  • 2 到 2^M 的幂的总和是 2^(M+1) - 1。我在高中时就知道证明,但现在对数学证明没有太多用处。 ;) 如果你尝试一下,你可以看到模式。 1、3、7、15、31、63、127、255等
  • 是的 M 的值是 log N^2 和 2 ^ (log N^ 2) 是 N^2 我希望它是正确的
  • 使用日志似乎是有意义的,直到 Saeed 指出它是错误的。我意识到 2 的幂之和基本上就是 2 * 最大值,即 N^2,所以 O(N^2)。日志没有进入它。
【解决方案2】:

这里有很多混淆,但重要的是Big-O notation 是关于增长率,或者如数学家所说的限制行为。一个函数将在 O(n*n) 中执行意味着执行时间将比例如 n 增加得快,但比例如 2^n 慢.

当使用big-O notation 进行推理时,请记住常量“不算数”。这个特定问题有一些怪癖。

  • 如果循环是常规 for 循环,N*N 表达式 it-self 将导致 O(log n*n) 复杂度...
  • ...但是,for 循环增量为 i = i*2 导致外部循环大约执行 log n 并且如果内部循环的内容以时间无关的方式运行,则函数将在 O(log n) 中n 个。
  • 但同样,内循环运行时间取决于 n,但它不会执行 n*n 次运行,而是大致记录 (n*n)/2 次循环。记住“常数不算数”并且我们最终会得到 O(n*n)。

希望这能解决问题。

【讨论】:

  • 不,for循环是i *= 2。不是i *= i
  • 循环增量不是i*=i它的i*=2
  • 你的解释不正确。如果内循环为 O(1)(与 n 无关),则外循环将以 O(log(n)) 运行。
【解决方案3】:

所以 sum ++ 将被执行 1 + 2 + 4 + 8 + ... + N*N,总共 log2(N*N) 次。几何级数之和 1 * (1 - 2 ^ log2(N*N)/(1 - 2) = O(N*N)。

【讨论】:

    【解决方案4】:

    你的外循环是log(N^2)->2*log(N)->log(N),你的内循环是N^2/2->N^2。因此,时间复杂度为 N^2*log(N)。

    关于基准,N=8 或 N=16 的值是荒谬的,循环中的时间与设置 JVM、缓存失败等有关。你必须:

    从最大的 N 开始,检查它的评估方式。

    使用每个 N 值进行多次运行。

    认为时间复杂度是衡量当 N 变得非常大时算法如何工作的指标。

    【讨论】:

    • 内循环 N^2/2 怎么样?我了解外循环的价值吗?
    • 好吧,我太快了。我正在考虑算术连续(当 i=2 时进行 1 次迭代,当 i = 3 时进行 2 次迭代......)但不认为 i 取值 1、2、4、8、16...... 这是一个总和几何系列的值,我必须再次检查。
    • 是的,就是这么想的,内部循环没那么简单
    • 1 + 2 = 3 (2^2 -1), 1 + 2 + 4 = 7 (2^3 - 1)... 一般来说,迭代次数为 2^i - 1对于给定的 i
    猜你喜欢
    • 2022-01-27
    • 2018-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-18
    相关资源
    最近更新 更多