Что такое О-большое (Big O) и зачем оценивать сложность алгоритма?
- Что такое асимптотическая сложность?
- Какие классы сложности вы знаете?
- Чем O(n) отличается от O(log n)?
О-большое описывает, как растёт время или память алгоритма с ростом входа n, отбрасывая константы и младшие слагаемые.
- Основные классы: O(1) < O(log n) < O(n) < O(n log n) < O(n²) < O(2ⁿ)
- Обычно говорят о худшем случае; средний и лучший называют отдельно
А ещё Константы важны на малых n, но на больших данных решает класс роста
Подробно
Точное время работы зависит от компьютера, языка и компилятора, поэтому алгоритмы сравнивают по тому, как растёт число операций при росте размера входа n. Запись O(f(n)) означает: начиная с некоторого n, затраты растут не быстрее, чем f(n), умноженная на константу.
При оценке:
- константы отбрасывают — O(2n) и O(n) один класс;
- младшие слагаемые отбрасывают — O(n² + n) это O(n²);
- разные входы обозначают разными буквами — обход двух массивов O(n + m), вложенный цикл по ним O(n·m).
Классы на примерах:
- O(1) — доступ к элементу массива по индексу, поиск в хеш-таблице в среднем;
- O(log n) — бинарный поиск: каждый шаг делит задачу пополам;
- O(n) — один проход по массиву;
- O(n log n) — хорошие сортировки сравнением;
- O(n²) — вложенный цикл по тем же данным, сортировка пузырьком;
- O(2ⁿ) — перебор всех подмножеств.
Разница огромная: при n = 1 000 000 алгоритм O(n log n) делает около 20 миллионов операций, а O(n²) — триллион.
Рядом с O используют Ω (оценка снизу) и Θ (точная оценка), но на собеседованиях чаще всего говорят «O» в смысле «как растёт в худшем случае».
Пример
def has_duplicates_slow(a): # O(n²): сравниваем каждую пару
return any(a[i] == a[j] for i in range(len(a)) for j in range(i + 1, len(a)))
def has_duplicates_fast(a): # O(n): множество с проверкой за O(1) в среднем
return len(set(a)) != len(a)Что хотят услышать
- Определение через рост затрат с ростом n.
- Правила: отбрасываем константы и младшие слагаемые.
- Классы сложности с примерами алгоритмов.
- Понимание практической разницы на больших n.
Частые ошибки
- Считать, что O(n) всегда быстрее O(n²) на любых данных — на малых n решают константы.
- Путать сложность по времени и по памяти.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✓Рост времени или памяти с ростом n без констант и младших слагаемых; O(log n) < O(n) < O(n log n) < O(n²)
- ✗Точное число операций алгоритма для конкретного n с учётом всех констант, поэтому O(2n) и O(n) — разные классы сложности
- ✗O(n²) всегда медленнее O(n) даже при n = 3
- ✗O-большое описывает только лучший случай
Что спросят дальше
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.