【问题标题】:Why is code like i=i*2 considered O(logN) when in a loop?为什么像 i=i*2 这样的代码在循环中被认为是 O(logN)?
【发布时间】:2017-08-02 21:04:45
【问题描述】:

为什么因为 i=i*2 是下面的循环的运行时间被认为是 O(logN)?

for (int i = 1; i <= N;) {
  code with O(1);
  i = i * 2;
}

【问题讨论】:

  • 你确定你的意思是包含乘法的行吗?整个循环具有日志复杂性。
  • 我的意思是,整个循环,对这个还是新的。

标签: time-complexity big-o logarithm


【解决方案1】:

看看 1024 = 210。数字 1 要加倍多少次才能得到 1024?

Times    1   2   3   4    5    6    7    8     9      10
Result   2   4   8   16   32   64  128  256   512    1024

所以你必须运行你的加倍循环十次才能得到 210一般来说,你必须运行你的加倍循环 n 次才能得到 2n。但是什么是n?它是 log2 2n,所以通常如果 n 是 2 的某个幂,则循环必须运行 log2n 次才能达到它。

【讨论】:

    【解决方案2】:

    要在O(logN) 中使用算法,对于任何 N,它都需要(大约)log N 步。在 N=32(其中 log 32 = 5)的示例中可以看出:

    i = 1 (start)
    i = 2
    i = 4
    i = 8
    i = 16
    i = 32 (5 iterations)
    i = 64 (abort after 6 iterations)
    

    一般来说,x 迭代后,i=2^x 成立。要联系i&gt;N,您需要x = log N + 1

    PS:在谈到复杂性时,log 基数 (2, 10, e, ...) 是不相关的。此外,如果您有 i &lt;= Ni &lt; N 则无关紧要,因为这只会将迭代次数更改一。

    【讨论】:

      【解决方案3】:

      你可以很简单地证明它。

      声明: 对于tth (0 base) 迭代,i=2^t 通过归纳证明。

      基础:2^0 = 1,实际上在第一次迭代中,i=1

      步骤:对于某些t+1i 的值为2*i(t)(其中i(t)t 迭代中i 的值)。根据归纳假设,我们知道i(t)=2^t,因此知道i(t+1) = 2*i(t) = 2*2^t = 2^(t+1),并且该主张成立。

      现在,让我们检查一下我们的停止条件。我们在 i &lt;= N 时迭代循环,根据上述声明,这意味着我们在 2^t &lt;= N 时迭代。通过在两边都执行log_2,我们得到log_2(2^t) &lt;= log_2(N),并且由于log_2(2^t) = t,我们得到我们在t &lt;= log_2(N) 时迭代——所以我们迭代Theta(log_2(N)) 次。 (这就是证明的结束)。

      【讨论】:

        【解决方案4】:

        i1 开始。在每次迭代中,您将 i 乘以 2,因此在第 K-th 次迭代中,i 将是 >2K-1.

        经过 K 次迭代后,2K-1 将大于(或大于)N.

        这意味着 N ≤ 2K-1

        这意味着 log2(N) ≤ K-1

        K-1 将是您的循环将运行的迭代次数,并且由于 K-1 大于或等于 log(N),你的算法是对数的。

        【讨论】:

          猜你喜欢
          • 2017-05-19
          • 1970-01-01
          • 2019-04-26
          • 1970-01-01
          • 2014-08-09
          • 2016-10-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多