如何准确识别O(nlogn)?

时间:2019-04-14 06:41:51

标签: python python-3.x algorithm time-complexity big-o

我从某种意义上理解了O(logn),O(logn)会快速增加,但输入较大时,增加速度会变慢。 我无法完全理解

  1. O(nlogn)

  2. 具有复杂度nlogn和复杂度n + logn的算法之间的差异。

我可以使用电话簿示例的修改和/或一些基本的python代码来理解这两个查询

4 个答案:

答案 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 nn相形见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的要点是只陈述增长最快的术语的增长率。

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)超线性增长。斜率增加(缓慢)。