Що таке складність алгоритму
Модуль 1Урок 1 з 37Безкоштовний модуль
Коли ви обираєте алгоритм, важливо не лише «чи працює», а й «як швидко росте час роботи, коли даних стає більше». Велике О описує верхню межу зростання: як змінюється кількість кроків відносно розміру вхідних даних . Це не секунди на годиннику — це тренд. Уявіть два ліфти в будинку: один піднімає по одному поверху за раз, інший — одразу на потрібний. На другому поверсі різниці майже немає; на сотому — величезна. Так само і можуть виглядати однаково на маленьких тестах, але обмеження на LeetCode розводять їх жорстко.
Складність оцінюють за кількістю елементарних операцій: порівнянь, присвоєнь, звернень до масиву. Константи і дрібні деталі реалізації відкидають — нас цікавить порядок зростання, коли стає дуже великим. Тому два алгоритми з однаковим великим О можуть відрізнятися в реальному часі, але на співбесіді спочатку називають клас складності, а вже потім обговорюють оптимізації.
Найкращий, середній і найгірший випадок
Один і той самий код може поводитися по-різному. Найкращий випадок — найкращий сценарій (наприклад, елемент одразу знайшли). Найгірший — найгірший (елемент у кінці або його немає). Середній — типовий сценарій. На співбесідах і в задачах з LeetCode зазвичай мають на увазі найгірший випадок, якщо не сказано інакше.
Приклад
Лінійний пошук у масиві довжини : найкращий випадок (знайшли на першій позиції), найгірший (перевірили всі елементи). Сортування злиттям має у всіх трьох випадках — стабільна поведінка. Середній випадок лінійного пошуку — теж , якщо елемент може бути на будь-якій позиції з однаковою ймовірністю. На практиці найгірший випадок часто важливіший: підступні тести на платформах якраз підбирають найгірший вхід.
Поширені класи великого О
— константний час: доступ до елемента масиву за індексом. — кожен крок ділить задачу навпіл: бінарний пошук у відсортованому масиві. — один прохід по даних. — типово для ефективного сортування. — вкладені цикли по : наївне порівняння кожної пари.
Порада
Порівнюйте класи за зростанням: . Якщо , різниця між і — мільйон проти трильйона операцій. Корисна евристика: за секунду сучасний сервер встигає приблизно простих операцій. з дає — це перевищення ліміту часу. Тримайте цю таблицю в голові перед вибором наївного перебору.
Не плутайте простір і час. Складність за памʼяттю описує додаткову памʼять: новий масив, словник, глибину стека рекурсії. Алгоритм може бути за часом і за памʼяттю (на місці), або навпаки — за часом сортування і за памʼяттю для копії. На співбесіді часто питають обидва показники.
Підрахунок кроків у циклах
Один цикл по — близько кроків, . Два вкладені — близько , . Цикл, що щоразу ділить діапазон навпіл, дає . Константи всередині (два проходи замість одного) на клас Big O не впливають. Намалюйте таблицю для : лінійний ріст лишається «читабельним», квадратичний одразу вибухає.
Типовий фрагмент
Три функції рахують кроки для різних — інтуїція класів складності. Код нижче лише для читання; писати й запускати розвʼязки задач ви будете на LeetCode.
def tally_constant(size):
ops = 0
ops += 1
return ops
def tally_linear(size):
ops = 0
for idx in range(size):
ops += 1
return ops
def tally_quadratic(size):
ops = 0
for i in range(size):
for j in range(size):
ops += 1
return ops
for n in [10, 100, 1000]:
print(n, tally_constant(n), tally_linear(n), tally_quadratic(n))
Натисніть «Запустити» — вивід зʼявиться тут
Увага
Велике О ігнорує константи: записують як . Нижчі доданки відкидають: — це .
Що запамʼятати
Велике О описує зростання в найгіршому випадку. Знайте базові класи й умійте оцінити вкладені цикли. Після кожної задачі проговоріть складність вголос.
Перевірка
4 питанняКілька питань за матеріалом уроку. Спроб — скільки завгодно.