【问题标题】:Time complexity of loop multiplying the value by two or three将值乘以二或三的循环时间复杂度
【发布时间】:2014-06-05 14:04:39
【问题描述】:

我在一个 SO 问题中找到了以下 for 循环。

我发现时间复杂度是O(n log n)

如果我们将k *= 2 更改为k *= 3,我将如何计算时间复杂度?

// 'int n' is defined somewhere
int var = 0;
for (int k = 1; k <= n; k *= 2)
   for (int j = 1; j <= n; j++)
      var++;

【问题讨论】:

    标签: c++ algorithm time-complexity


    【解决方案1】:

    时间复杂度仍为O(n log n)

    对于k *= 2log 将以 2 为基数。

    对于k *= 3log 将以 3 为基数。

    但是log 的基数的变化只会通过一个常数因子影响结果(这可以从log<sub>b</sub>a = log<sub>c</sub>a / log<sub>c</sub>b,对于任何基数c 的事实得出),这在 big -O 表示法,因此它们具有相同的时间复杂度。


    我们从哪里得到log<sub>2</sub>n

    嗯,k 的值是这样的:

    1, 2, 4, 8, 16, ..., 2m  for some m, where 2m <= n < 2m+1
    = 20 + 21 + 22 + ... + 2m

    当然上面只有m+10m)术语,所以循环运行m+1 次。

    现在如果我们可以使用一些基本的对数来得到mn

    2m = c.n   for some constant c, where 1 <= c < 2
    log22m = log2(c.n)
    m log22 = log2(c.n)
    m.1 = log2c + log2n
    m = O(log2c + log2n)
      = O(log2n)               // constant terms can be ignored
    

    我们也可以对k *= 3 采用与上述完全相同的方法,只需将2 替换为3

    【讨论】:

      【解决方案2】:

      答案是N×log3N。

      要知道为什么,你需要弄清楚为什么原始问题的答案是 N×log2N。它会执行多少次(我们称之为k)?它将根据需要执行多次,以将2 与自身相乘,这样结果就会超过N。也就是说,2k > N。现在对表达式两边都取对数(对数的定义可以看here),看到k > log2N.

      我们之所以使用2 作为对数的底,是因为左边指数的底是2。很容易看出,如果 exponen 的基数是 3,则应用 log3 会得出您正在解决的问题的答案。

      【讨论】:

        【解决方案3】:

        您可以使用 Sigma 符号正式且有条不紊地进行:

        查看此document 的最后一张幻灯片。

        【讨论】:

          猜你喜欢
          • 2013-09-13
          • 2013-01-17
          • 2023-02-09
          • 2021-02-15
          • 2013-12-08
          • 2022-11-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多