O(nlogn)
具有复杂度nlogn和复杂度n + logn的算法之间的差异。
我可以使用电话簿示例的修改和/或一些基本的python代码来理解这两个查询
答案 0 :(得分:5)
您如何看待O(n ^ 2)
?
就个人而言,我喜欢将其视为O(n)
次O(n)
次的工作。
人为设计的O(n ^ 2)
算法将迭代0, 1, ..., n - 1
中的所有数字对
def print_pairs(n):
for i in range(n):
for j in range(i + 1, n):
print('({},{})'.format(i, j))
使用与上述类似的逻辑,您可以O(log n)
次O(n)
工作,并且时间复杂度为O(n log n)
。
作为一个例子,我们将使用二进制搜索来查找数组中元素的所有索引。
是的,我知道这是一个愚蠢的示例,但是在这里,我不想关注算法的有用性,而是关注复杂性。为了我们算法的正确性,让我们假设输入数组已排序。否则,我们的二进制搜索将无法正常工作,并且可能会无限期运行。
def find_indices(arr):
indices = []
for num in arr:
index = binary_search(arr, 0, len(arr), num)
indices.append(index)
return indices
def binary_search(arr, l, r, x):
# Check base case
if r >= l:
mid = l + (r - l)/2
# If element is present at the middle itself
if arr[mid] == x:
return mid
# If element is smaller than mid, then it
# can only be present in left subarray
elif arr[mid] > x:
return binary_search(arr, l, mid-1, x)
# Else the element can only be present
# in right subarray
else:
return binary_search(arr, mid + 1, r, x)
else:
# Element is not present in the array
return -1
关于第二个问题,
当然,log n << n
由于n趋于无穷大,所以
O(n + log n) = O(n)
从理论上讲,log n
与n
相形见as,因为我们任意大,所以我们不在Big O分析中包括它。
与实践并列,如果您的算法遇到性能和/或扩展问题,您可能需要考虑这项额外的log n
工作。
答案 1 :(得分:1)
log n
是一个比n
慢得多的函数。当计算机科学家谈到big-O时,他们对极大的输入值功能的增长很感兴趣。函数在某个小数点或拐点附近的作用并不重要。
许多常见算法的时间复杂度为n log n
。例如,merge sort要求n
进行log_2(n)
步,因为输入数据被分成两半。在研究了算法之后,它的复杂度为n log n
的事实可能是凭直觉得出的,但是通过研究描述(递归)算法的递归关系,您可以得出相同的结论-在这种情况下,{{ 1}}。更一般而言,但也许至少是直观上,master theorem可以用于得出此T(n) = 2 * T(n / 2) + n
表达式。简而言之,如果对于某些算法为何具有特定的运行时间还不是很清楚,那么不要感到害怕-您可以采用多种方法进行分析。
关于“复杂度n + log n”,这不是大O表示法倾向于使用的方式。您可能有一个可以n log n
起作用的算法,但是我们不称其为n + log n
,而是称其为O(n + log n)
,因为O(n)
的增长速度远远快于{{1} } n
术语可以忽略。 big-O的要点是只陈述增长最快的术语的增长率。 p>
与log n
相比,log n
更快。如果n log n
是将项目插入自平衡搜索树的时间复杂度,则log n
就是将log n
项插入这种结构的复杂度。
答案 2 :(得分:0)
有一本Grokking algorithms很棒的书,用一种非常简单的语言详尽地解释了算法复杂性检测(以及其他)。
答案 3 :(得分:0)
从技术上讲,复杂度为O(n + log n)和复杂度为O(n)的算法是相同的,因为当n增长时,log n项可以忽略不计。
O(n)线性增长。斜率是恒定的。 O(n log n)超线性增长。斜率增加(缓慢)。