【问题标题】:What is the time complexities of these two loops?这两个循环的时间复杂度是多少?
【发布时间】:2015-11-10 15:01:33
【问题描述】:

对于这两个 while 循环,我想弄清楚大 O 复杂度。没有详细给出这些选项:(O(log N),O(sqrt(N),O(N),O(N log N),O(N·N)。这是一个古老的考试问题,我找不到答案。

问题 1

int i, j = N;
while (i < j) {
  i += 2 * j + 1;
  j++;
} 

问题 2

int i = 1, j = N;
while (i < j) {
  i += i;
  j--;
}

第一个的答案应该是 O(N·N),第二个的答案应该是 O(log(N))。如果有人能解释答案,那就太好了。

【问题讨论】:

  • 请写下为什么你认为第一个是O(n^2),第二个是O(log n)。
  • 在第一季度,int i 的值未定义。错字?
  • 编辑您的第一个 sn-p。它令人困惑。
  • 第一个循环是 O(1),第二个是 O(logN)
  • 第一个循环包含未定义的行为,因为i 未初始化。

标签: c loops while-loop big-o


【解决方案1】:

第一个,如果 i>=j,它是 O(1)。如果 i 和 j 是正数,它将循环一次,并结束 O(1)。

如果 i 为负而 j 不是 (>= 0),您会看到 i 从 i 缓慢增长到 0,然后当 i 为正时,循环停止。在这种情况下,i 至少增长了 N/2。

如果 i 和 j 都是非常大的负数,则 i 将变得更负,直到 j 达到 0。在此期间,i 将变得更负,至少每次 abs(j),即 O(N * N)。当 j 达到 0 时,已经是 O(N * N),所以即使 j==0 时确实很快,但答案应该是 O(N * N)。

对于最后一种情况,我遵循如下序列(假设 Z 是大于 abs(N) 的正数):

-Z, -Z-2Z+1, -Z-2Z+1-2(Z-1)+1, -Z-2Z+1-2(Z-1)+1-2(Z-2 )+1 .... (直到 j 达到 0).. 然后达到一些最大负数的粗略大小 Z 的平方 (比如 W).. 然后变成 W+2+1, W+2+1+4+1 , W+2+1+4+1+6+1 ... 直到 i>j.

因此,在所有情况下,第一个问题都是 O(N*N)。

第二个每次都将 i 翻倍,O(log N) 也是如此。想象一下,如果 j 是一个非常大的数字 1000000,并且 i = 1。所以 (i, j) 将是 (2, 999999), (4, 999998), (8, 999997, (16...) (32, ) (64, ) (128, ) (256, ) (512, ) (1024, ) (2048, ) (4096, ) (8192, ) (16384, ) (32768, ) (65536, ) (131092, ) (262144 , ) (524288, 999981),共 19 步。

【讨论】:

  • 您能否详细说明为什么您认为它在第一个 sn-p 中没有进入循环?
  • @Olaf 在 i 为正的情况下,第一次迭代会使 i > j,(即 i + j*2+1 > j+1)
  • @Lashane:由于i 的初始值未指定(错误?),所以现在无法回答这个问题。在 OP 澄清之前,这只是猜测。
  • @Olaf 这个问题不是关于 C UB,而是关于 bigO,所以我们可以假设 i=0/1any random value,对于第一种情况 O(1) 和第二种 O(N)跨度>
  • @Lashane 但是大 O 是基于更糟糕的情况,所以我们不得不假设它是 O(N) 而不是 O(1)
【解决方案2】:

问题 1

您没有为i 指定值,因此对于一般情况实际上无话可说。

但是,如果我们假设i 不依赖于N,那么运行时是O(1)

解释

对于大-N 限制:

  • i 每次迭代都会增长 2N
  • j 近似不变。
  • i 需要成长为 N
  • 因此需要O((N - i_0) / 2N) = O(1)时间。

这也直接说明如果i_0N的函数f(N),则运行时为O(f(N)/N)


问题 2

运行时是O(log N)

扩展

对于大-N 限制:

  • i 每次迭代加倍。
  • j 近似不变。
  • i 需要成长为 N
  • 因此,它需要O(log(N-i_0)) = O(log N) 时间。

最后一点,根据问题中O(log N)N 的用法,此问题假定N 为正数。

【讨论】:

    【解决方案3】:

    在问题 1 中,由于 i 和 j 都被初始化为 N。while 循环不会执行。因此,O(1)。

    第二个问题就是 O(logN),因为 i 每次迭代都会加倍。

    【讨论】:

    • 'i' 未初始化,因此它有可能执行。 BIG O 基于更糟糕的情况,这意味着第一个循环将是 O(N)
    • @scerrecrow 不一定是O(N),想象一下如果i = -N!(教师功能)会发生什么。
    猜你喜欢
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多