← Назад к вопросам

Что такое О большая?

1.0 Junior🔥 221 комментариев
#DevOps и инфраструктура#Django

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое О большая

О большая (Big O Notation) — это математическая нотация для описания времени выполнения и пространства памяти алгоритма в зависимости от размера входных данных. Она показывает, как алгоритм масштабируется при увеличении размера задачи.

Основная идея

Big O описывает наихудший сценарий выполнения алгоритма. Когда размер входных данных растет, как растет время выполнения?

# O(1) — константное время
def get_first(arr):
    return arr[0]  # Всегда берем первый элемент, не важно размер

# O(n) — линейное время
def find_element(arr, target):
    for item in arr:  # Может пройти весь массив
        if item == target:
            return item
    return None

# O(n^2) — квадратичное время
def bubble_sort(arr):
    for i in range(len(arr)):
        for j in range(len(arr) - 1):  # Вложенный цикл
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]

Основные сложности

O(1) — Константная сложность

  • Время не зависит от размера входных данных
  • Примеры: доступ к элементу массива по индексу, словарь
def first_element(arr):
    return arr[0]

def dict_lookup(d, key):
    return d[key]

O(log n) — Логарифмическая сложность

  • Время растет логарифмически (очень медленно)
  • Пример: бинарный поиск
def binary_search(arr, target):
    left, right = 0, len(arr) - 1
    while left <= right:
        mid = (left + right) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return -1

O(n) — Линейная сложность

  • Время растет пропорционально размеру входных данных
  • Примеры: линейный поиск, проход по массиву
def linear_search(arr, target):
    for i in range(len(arr)):
        if arr[i] == target:
            return i
    return -1

def sum_array(arr):
    total = 0
    for num in arr:
        total += num
    return total

O(n log n) — Линеарифметическая сложность

  • Примеры: эффективные сортировки (merge sort, quick sort)
def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    
    return merge(left, right)

O(n^2) — Квадратичная сложность

  • Примеры: неэффективные сортировки (bubble sort, insertion sort)
def bubble_sort(arr):
    for i in range(len(arr)):
        for j in range(len(arr) - 1 - i):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    return arr

O(2^n) — Экспоненциальная сложность

  • Время удваивается с каждым дополнительным входом
  • Примеры: рекурсивный Фибоначчи, перебор всех подмножеств
def fibonacci_naive(n):
    if n <= 1:
        return n
    return fibonacci_naive(n-1) + fibonacci_naive(n-2)
    # fibonacci(40) выполняется минут, не секунды!

O(n!) — Факториальная сложность

  • Очень редко встречается, крайне неэффективна
  • Примеры: перебор всех перестановок
def generate_permutations(arr):
    if len(arr) <= 1:
        return [arr]
    
    perms = []
    for i in range(len(arr)):
        rest = arr[:i] + arr[i+1:]
        for perm in generate_permutations(rest):
            perms.append([arr[i]] + perm)
    return perms

Сравнение сложностей

При n = 1000:

  • O(1): 1 операция
  • O(log n): 10 операций
  • O(n): 1000 операций
  • O(n log n): 10000 операций
  • O(n^2): 1000000 операций
  • O(2^n): невозможно вычислить за разумное время

Пространственная сложность

Big O также описывает память:

def create_list(n):
    arr = [0] * n  # O(n) памяти
    return arr

def bubble_sort_inplace(arr):
    for i in range(len(arr)):
        for j in range(len(arr) - 1 - i):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
    # O(1) памяти — сортирует на месте

Как анализировать сложность

  1. Посчитай циклы:
# O(n) — один цикл
for i in range(n):
    print(i)

# O(n^2) — вложенные циклы
for i in range(n):
    for j in range(n):
        print(i, j)
  1. Посмотри на рекурсию:
# O(log n) — делим на 2 каждый раз
def binary_search(arr, target, left, right):
    if left > right:
        return -1
    mid = (left + right) // 2
    if arr[mid] == target:
        return mid
    elif arr[mid] < target:
        return binary_search(arr, target, mid + 1, right)
    else:
        return binary_search(arr, target, left, mid - 1)
  1. Игнорируй константы:
# O(2n) = O(n) — константы не важны
def double_loop(arr):
    for i in range(len(arr)):
        print(i)
    for i in range(len(arr)):
        print(i)

Best Practices

  1. Выбирай правильный алгоритм — O(n log n) намного лучше O(n^2)
  2. Используй встроенные функции — они оптимизированы
  3. Профилируй реальный код — Big O теория, практика может отличаться
  4. Помни о константах — O(n) с большой константой может быть медленнее O(n log n)

Big O — фундаментальная концепция для понимания производительности алгоритмов и написания масштабируемого кода.

Что такое О большая? | PrepBro