【问题标题】:Big O - O(log(n)) code example大 O - O(log(n)) 代码示例
【发布时间】:2013-06-11 22:45:24
【问题描述】:

就像大 O 符号“O(1)”可以描述以下代码:

O(1):

    for (int i = 0; i < 10; i++) {
        // do stuff 
        a[i] = INT;
    }

O(n):

    for (int i = 0; i < n; i++) {
        // do stuff 
        a[i] = INT;
    }

O(n^2):
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            // do stuff
            a[i][j] = INT;
        }
    }
  • O(log(n)) 可以描述什么代码?

另一个问题:

  • 对于“大 O 问题”(当获取大量数据作为输入时该怎么办)有哪些解决方案?

【问题讨论】:

  • O(log n) 通常是在算法分而治之的时候,比如二分搜索或类似的。
  • 这是一个实用的(编码测试)示例leetcode.com/problems/find-peak-element => 查看问题和解决方案

标签: java algorithm big-o


【解决方案1】:

经典例子:

while (x > 0) {  
   x /= 2;  
}  

这将是:

Iteration |   x
----------+-------
    0     |   x
    1     |  x/2
    2     |  x/4
   ...    |  ...
   ...    |  ...
    k     |  x/2^k 

2k = x → 两边应用对数 → k = log(x)

【讨论】:

  • 伟大而简单的例子,正是我想要的!谢谢你:)
  • 我错过了你得到 2^k = x 的那一刻,而它曾经是 x/2^k ?
  • 1 是最后一次迭代。所以我想知道在哪一点上这将被评估为 1。
  • 有史以来最好的解释。非常感谢。
  • @DanielGurinov,x/2^k 的除法最终会得到 1。等式这会给你, 1=x/2^k ,相当于, x=2^k ,关于应用日志。当 b 的 y 次方等于 x 时: b^y = x ;在这种情况下 2^y=x 那么 x 的以 b 为底的对数等于 y: logb(x) = y ;在这种情况下,k = log(x) 意味着 log base 2
【解决方案2】:

带有 for 循环的最简单代码,可用于表示:

O(1):

function O_1(i) {
    // console.log(i);
    return 1
}

O(n):

function O_N(n) {
    count = 0;
    for (i = 0; i < n; i++) {
        // console.log(i);
        count++;
    }
    return count
}

O(n²):

function O_N2(n) {
    count = 0;
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            // console.log(i, j);
            count++;
        }
    }
    return count
}

O(Log2(n)):

function O_LOG_2(n) {
    count = 0;
    for (var i = 1; i < n; i = i * 2) {

        count++;
    }
    return count
}

O(Sqrt(n)):

function O_SQRT(n) {
    count = 0;
    for (var i = 1; i * i < n; i++) {
        // console.log(i);
        count++;
    }
    return count
}

【讨论】:

    【解决方案3】:

    根据定义,log(n)(我的意思是以 2 为底的对数,但底数实际上并不重要)是您必须乘以 2 才能得到 n 的次数。所以,O(log(n)) 代码示例是:

    i = 1
    while(i < n)
        i = i * 2
        // maybe doing addition O(1) code
    

    在实际代码示例中,您可以在二进制搜索、平衡二进制搜索树、许多递归算法、优先级队列中遇到 O(log(n))。

    【讨论】:

      【解决方案4】:

      对于 O(logn),请查看任何涉及分治策略的代码 示例:合并排序和快速排序(在这些情况下,预计运行时间为 O(nlogn))

      【讨论】:

        【解决方案5】:

        二分搜索是一个例子 O(log(n))。 http://en.wikipedia.org/wiki/Binary_search_algorithm.

        【讨论】:

          【解决方案6】:

          可能值得强调的是,您描述的较低复杂度算法是较高复杂度算法的子集。换句话说,

          for (int i = 0; i < 10; i++) {
              // do stuff 
              a[i] = INT;
          }
          

          在 O(1) 中,但也在 O(n)、O(n²) 中,如果你想聪明一点,O(log(n))。为什么?因为所有的恒定时间算法都受到一些线性、二次等函数的限制。

          对于“大 O 问题”有哪些解决方案(当获取大量数据作为输入时该怎么做)?

          这个问题对我来说没有多大意义。 “大量数据”是相当随意的。不过,请记住,大 O 并不是时间复杂度的唯一衡量标准。除了测量最坏情况的时间复杂度外,我们还可以检查最佳情况和平均情况,尽管计算起来可能有点棘手。

          【讨论】:

            【解决方案7】:

            在二分搜索的情况下,您试图找到最大的迭代次数,因此搜索空间可以分成两半的最大次数。这是通过重复将搜索空间的大小 n 除以 2 直到达到 1 来实现的。

            让我们给出标签 x 需要将 n 除以 2 的次数。由于除以 2,x 次等于除以 2^x,因此您最终必须求解这个等式:

            n/2^x = 1,变成n = 2^x,

            所以使用对数,x = log(n),所以二进制搜索的 BIG - O 是 O(log(n))

            重申一下:x 是在将大小为 n 的空间缩小到大小为 1 之前,您可以将其分成两半的次数。

            http://www.quora.com/How-would-you-explain-O-log-n-in-algorithms-to-1st-year-undergrad-student

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-12-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多