【问题标题】:How to find out whether a given function is O(n)?如何找出给定函数是否为 O(n)?
【发布时间】:2016-05-07 15:35:37
【问题描述】:

我在测试中被问到以下问题:

以下哪些属于 O(n)?

a) n + lgn b) n + 2n c) n + n^2 d) 1000n + 4500lgn + 54n

我知道 O(n) 的时间复杂度取决于元素的数量,因此随着元素数量的增加,完成操作所需的时间也会增加。按照这个逻辑,说a和c的时间复杂度是O(n)对吗?

【问题讨论】:

  • O(n) 表示给定函数的最大时间复杂度为 n^1 或更小,如 log(n) 等。所以 a,b 和 d 可以是 O(n)。不是 c ,因为 c 包含 n^2 所以你可以说它是 O(n^2)。

标签: java data-structures time big-o


【解决方案1】:

考虑 O(n) 的定义,即对于某些函数 f(n) 必须有两个正常数,ck,例如 c > 0k > 0n >= k0 <= f(n) <= cn。如果我们可以证明常量 ck 存在,那么函数就是 O(n)(如果这些常量不存在,那么函数实际上大于 O(n))。

让我们看看F(n) = n + lg(n)。这是O(n)吗?如果是这样,那么我们应该很容易找到 c 和 k 的值。

0 <= f(n) <= cn
0 <= n + lg(n) <= cn

让我们将k 设置为 2,并考虑 n 为 2 的基本情况(因为 n >= k)。

0 <= 2 + lg(2) <= c * 2
0 <= 2 + 1 <= 2c
0 <= 3 <= 2c
0 <= 3/2 <= c

让我们看看函数在 n 增加时的行为(让 n = 4 看看会发生什么)。

0 <= 4 + lg(4) <= c * 4
0 <= 4 + 2 <= 4c
0 <= 6 <= 4c
0 <= 6/4 <= c
0 <= 3/2 <= c    .. take a look at that, it doesn't matter how large n becomes, c is 3/2

所以我们找到了我们的常数(c=3/2 和 k=2),所以这个函数的正式定义是 O(n)。

让我们看看F(n) = n + n^2。这是O(n)吗?应该很明显不是,它实际上是 O(n^2),但是让我们看看我们是否可以找到值 c 和 k。

0 <= f(n) <= cn
0 <= n + n^2 <= cn

让我们再次将k 设置为 2,并考虑 n = k 的基本情况。

0 <= 2 + 2^2 <= c*2
0 <= 2 + 4 <= 2c
0 <= 6 <= 2c
0 <= 3 <= c   .. so IF this is O(n), c is at least 3

让我们看看随着 n 的增加(现在 n = 4)会发生什么

0 <= 4 + 4^2 <= 4c
0 <= 4 + 16 <= 4c
0 <= 20 <= 4c
0 <= 20/4 <= c
0 <= 5 <= c       .. last time c was 3, now its 5 ... as n increases, c is not constant!

这个函数不是 O(n) - 我们找不到常量值 ck 因为它们根本不存在。

考虑 f(n) = 5n ... 这是 O(n)(在这种情况下,很明显 c 是 5)。考虑 f(n) = n * n .. 这不是 O(n) (c 将等于 n,它不是常数)。我们真正要说的是,我们的函数 f(n) 以另一个函数 g(n) 乘以某个常数为界。当我们询问一个函数是否为 O(n) 时,我们让 g(n) = n,但 n^2lgnnlgn 都是有趣的边界(这可能会在测试中)。

n + n^2 是 O(n^2) 吗?查找值c &gt; 0k &gt; 0n &gt;= k 应该不会有问题,例如0 &lt;= n + n^2 &lt;= cn^2

看看 https://xlinux.nist.gov/dads//HTML/bigOnotation.html进一步阅读。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-17
    • 2022-01-16
    • 1970-01-01
    相关资源
    最近更新 更多