Оцінювання складності при застосуванні стратегій розроблення алгоритмів

Розділ: Алгоритми та обчислювальна складність

📌 Про що ця тема


Тут перевіряють, чи вмієш оцінити, скільки «роботи» виконає алгоритм залежно від розміру вхідних даних, і як цей обсяг змінюється, коли задачу розвʼязують різними стратегіями (повний перебір, «розділяй і володарюй», жадібний метод, динамічне програмування). Ключове поняття — обчислювальна складність, яку записують через О-нотацію (велике «О»).


📖 Головне


• Обчислювальна складність — це залежність кількості елементарних операцій (або обсягу памʼяті) від розміру входу n. Розрізняють часову й просторову складність.

• О-нотація описує порядок зростання при великих n, відкидаючи сталі й молодші доданки. Напр., 3n² + 5n + 7 = O(n²).

• Основні класи від найкращого до найгіршого: O(1) — стала; O(log n) — логарифмічна; O(n) — лінійна; O(n·log n); O(n²) — квадратична; O(n³); O(2ⁿ) — експоненційна; O(n!) — факторіальна.

• Повний перебір (brute force): перебирають усі варіанти. Часто дає O(2ⁿ) або O(n!) — надійно, але повільно.

• Розділяй і володарюй: задачу ділять на підзадачі, розвʼязують їх і обʼєднують. Сортування злиттям і швидке сортування — O(n·log n); двійковий пошук — O(log n).

• Жадібний метод: на кожному кроці беруть локально найкращий варіант. Зазвичай швидкий (часто O(n·log n) або O(n)), але не завжди дає оптимум.

• Динамічне програмування: зберігають розвʼязки підзадач, щоб не рахувати їх двічі. Перетворює експоненту на поліном (напр., числа Фібоначчі: з O(2ⁿ) рекурсії до O(n)).

• Оцінюють найгірший випадок (worst case) — верхню межу; іноді середній і найкращий.

• Вкладені цикли множать складність: один цикл по n — O(n), два вкладені — O(n²).


🔢 Як це працює на прикладі


Пошук елемента у відсортованому масиві з n = 1000:

• Лінійний пошук — перебір підряд, у гіршому разі 1000 порівнянь → O(n).

• Двійковий пошук (розділяй і володарюй) — щоразу відкидаємо половину: 1000 → 500 → 250 → … ≈ log₂1000 ≈ 10 порівнянь → O(log n).

Висновок: зміна стратегії зменшила роботу з 1000 до ~10 операцій.


Числа Фібоначчі:

• Наївна рекурсія F(n)=F(n−1)+F(n−2) повторно рахує ті самі значення → O(2ⁿ).

• Динамічне програмування зберігає вже обчислені F → O(n). Для n = 40 це різниця між ~мільярдом і 40 операціями.


⚠️ Типові помилки


• Залишають сталі й коефіцієнти: пишуть O(2n) або O(n²+n) замість O(n) і O(n²).

• Плутають вкладені й послідовні цикли: два окремі цикли — це O(n)+O(n)=O(n), а вкладені — O(n²).

• Вважають, що жадібний метод завжди дає оптимальний результат — ні, лише для певних задач.

• Думають, що «розділяй і володарюй» завжди швидше за перебір — обʼєднання підзадач теж має ціну.

• Плутають часову і просторову складність: динамічне програмування зменшує час, але часто витрачає більше памʼяті.


🎯 Що завчити напамʼять


• Порядок класів: O(1) < O(log n) < O(n) < O(n·log n) < O(n²) < O(2ⁿ) < O(n!).

• Двійковий пошук — O(log n); якісні сортування — O(n·log n); вкладені цикли — O(n²).

• О-нотація відкидає сталі та молодші доданки.

• Чотири стратегії: перебір, розділяй і володарюй, жадібний, динамічне програмування.


🧠 Перевір себе


1. Яка складність у O-нотації для 5n² + 100n + 3?

2. Яка складність двійкового пошуку?

3. Яка стратегія перетворює рекурсію Фібоначчі з O(2ⁿ) на O(n)?

4. Один цикл по n усередині іншого циклу по n — яка складність?


Відповіді: 1 — O(n²); 2 — O(log n); 3 — динамічне програмування; 4 — O(n²).

Перевірити себе на практиці

Прочитати — половина справи. Далі потрібні завдання цієї ж теми з розбором кожної відповіді: саме на них видно, чи справді тема закрита.