如何识别代码片段的Big-O表示法是否为对数时间O(logn)?

时间:2019-02-10 21:00:25

标签: algorithm data-structures big-o

有人可以帮助我了解如何识别给定的代码片段是否是对数时间吗?我似乎无法理解这个概念。谢谢。

-一个很好的例子。

3 个答案:

答案 0 :(得分:1)

如果将输入分成相等或几乎相等长度的部分,然后仅在输入的一部分中继续进行操作(搜索,排序等),则代码受Log(n)约束。 / p>


示例:

  1. 二进制搜索排序的数组:在这里,您将输入数组划分为两个,然后仅继续进行部分搜索。复杂度为O(Log 2 (n))。

  2. 搜索m路径树:在这里,您的节点具有m路径。您可以从这m条路径中选择一种,然后继续在树上搜索。复杂度为O(Log m (n))。

答案 1 :(得分:1)

算法的时间复杂度为O(log(n)),它在每次迭代中将输入“削减”一半。
当然,经典示例是-二进制搜索。在每一步中,您将“问题大小”减半,这意味着在一次迭代之后,大小将为n / 2,在经过2步n / 2 ^ 2之后,因此在经过i步之后-{{1} }。该算法将在大小为n / 2 ^ i时终止,因此满足条件1的{​​{1}}是运行时间。
求解该方程式,我们得到i => n / 2 ^ i = 1,从而给了我们n = 2 ^ i的时间复杂度。

编辑:

更准确地说,我注意到没有必要精确地减少一半,因为运行时间只需要精确地i = log(n)个操作,而不是O(i) = O(log(n))个操作(因此也可以O(log(n))每次迭代的时间开销。
另外,我的示例仅演示了log(n)的情况,但是一种算法可能(例如)将输入“削减”为原始大小的1/3,从而得到O(1)
那么,为什么不指定日志的基础呢?
在这种情况下,我们通常指的是log_2,但是这里的n / 3 ^ ilog2无关,而O(log_i(n)) = O(log_j(n))是一个常数。

答案 2 :(得分:1)

通常,您会在“分而治之”类型算法中花费main-app-dir - app.py - api -- __init__.py -- server.py - open-source-package -- requirements.txt -- open-source-package --- __init__.py --- api ---- __init__.py ---- response.py 时间来查找代码。这意味着我们将问题分解为较小的部分,然后求解结果。

例如,在二进制搜索中:

open-source-package

此代码将您的搜索空间分成越来越小的子问题。每次将搜索空间减少一半时,您只能将整数除以logN的一半。

可以看到类似的算法,例如mergesort,该算法将数组递归地分成两半进行排序。 Mergesort本质上是:

mid = (hi + lo) / 2
if element == arr[mid]: element found, return
if element > arr[mid]: search(mid, hi)
else: search(lo, mid)

这将创建一个子问题树,如下所示:

logN

每个合并都在a = mergesort(arr[:len(arr)/2]) #left side b = mergesort(arr[len(arr)/2:]) #right side merge(a, b) 中进行,并且mergesort构建的子问题树的高度为 4 / \ 2 2 #mergesort left and right / \ / \ 1 1 1 1 #cannot break problem down further \ / \ / 2 2 #merge \ / 4 #merge (每个下一级除以2,您只能除以2 logN次)。这样可以使O(N)的合并时间为LogN,每次合并的时间为O(N)

另一个例子是诸如percolate_up或percolate_down之类的堆操作。当您拥有诸如二叉树之类的数据结构时,每个节点有两个孩子,树的高度为LogN