【问题标题】:Trying to understand the reason for this time complexity试图了解这种时间复杂度的原因
【发布时间】:2022-02-02 07:21:13
【问题描述】:

我正在尝试计算这两种算法的时间复杂度。我所指的这本书详细说明了每种方法的这些时间复杂度。

A) 算法 A:O(nlogn)

int i = n;
while (i > 0) 
{
  for (int j = 0; j < n; j++)
    System.out.println("*");
  i = i / 2;
}

B) 算法 B:O(n)

while (n > 0) 
{
  for (int j = 0; j < n; j++)
    System.out.println("*");
  n = n / 2;
}

我可以看到算法如何。 A 是O(nlogn)。 for 循环是 O(n),while 循环是 O(logn)。但是我没有看到 AlgoB 的时间复杂度是 O(n)。我也期待它是O(nlogn)。任何帮助将不胜感激。

【问题讨论】:

  • 假设n 是一百万。 for 循环将在 B 中迭代多少次?
  • 您可以尝试证明第二种情况下打印的星数在n2*n-1之间,对于任何n&gt;0
  • 请注意,虽然外循环在两者中执行的迭代次数相同,但内循环不会。
  • 模糊的标题。编辑更具体。 什么的时间复杂度?

标签: java time-complexity


【解决方案1】:

让我们从数学的角度来看看算法 B。

在第一个循环中打印的* 的数量是n。在每个后续循环中打印的* 的数量最多为 n/2。该递归关系导致序列:

n + n/2 + n/4 + n/8 + ...

如果这是一个无限序列,那么总和可以用公式 n/(1 - r) 表示,其中 r是项之间的因子。在这种情况下,r 是 1/2,因此无限序列的和为 2(n)。

您的算法肯定不会永远持续下去,而且每次循环时,它打印的星数可能还不到前一个循环的一半。因此打印的星数小于或等于 2(n)。

由于时间复杂度是常数因子,所以算法是O(n)。

这个概念称为摊销复杂度,它平均循环中的操作成本,即使某些操作可能相对昂贵。请参阅this questionthe Wikipedia page 以获取有关摊销复杂性的更详尽说明。

【讨论】:

  • 感谢您回答这个问题。这是有道理的。你能解释一下你是如何想出 n/4 和 n/8 等模式中的下一个数字的吗?
  • 来自您的代码。它在每个循环中将 n 除以 2。
【解决方案2】:

算法 B 在每次迭代时打印一半的开始。假设 n=10,则:

n=10 -> 10*
n=5 -> 5*
n=2 -> 2*
n=1 -> 1*

总共打印了 18 个*。您将打印n + n/2 + n/4 + ... + n/(2^i) 星星。 i 值多少钱?它等于 n 变为 0 所需的步数。换句话说,它是指数 2 必须提高到产生n:log_2(n)。你得到了图片中的总和:

可以近似为 O(n)。

【讨论】:

    猜你喜欢
    • 2020-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-11
    • 2019-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多