Как идентифицировать методы со сложностью выполнения O(n): подробное руководство

Чтобы определить, имеет ли метод сложность выполнения O(n), необходимо проанализировать его поведение и то, как он масштабируется в зависимости от размера входных данных. Вот несколько общих рекомендаций и примеров, которые помогут вам определить такие методы:

  1. Ищите линейные итерации: если метод содержит цикл, который один раз проходит по элементам массива, списка или любой другой структуры данных, то, скорее всего, его линейная сложность во время выполнения равна O(n). Например:
def linearSearch(arr, target):
    for element in arr:
        if element == target:
            return True
    return False
  1. Рассмотрим алгоритмы с одним обходом. Методы, выполняющие один проход по входным данным, например объединение двух отсортированных массивов или поиск максимального элемента в массиве, часто имеют линейную временную сложность. Например:
def mergeSortedArrays(arr1, arr2):
    merged = []
    i, j = 0, 0

    while i < len(arr1) and j < len(arr2):
        if arr1[i] < arr2[j]:
            merged.append(arr1[i])
            i += 1
        else:
            merged.append(arr2[j])
            j += 1

    # Append remaining elements
    merged.extend(arr1[i:])
    merged.extend(arr2[j:])

    return merged
  1. Анализ рекурсивных алгоритмов. Некоторые рекурсивные методы имеют сложность O(n), если каждый рекурсивный вызов обрабатывает один элемент или уменьшает размер задачи на постоянный коэффициент. Примеры включают рекурсивный обход связанного списка или выполнение поиска в глубину в дереве.
def recursiveSum(node):
    if node is None:
        return 0
    return node.value + recursiveSum(node.next)

В этом случае сложность зависит от размера связанного списка, который линейно масштабируется в зависимости от количества узлов.