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

Определение

Экспоненциальная сложность означает, что время выполнения удваивается с каждым увеличением размера входных данных на единицу.

Формула

Характеристики

  • Время растет экспоненциально
  • Каждый дополнительный элемент удваивает время
  • Практически непригодно для больших n
  • Часто встречается в наивных рекурсивных решениях

Рост времени выполнения

n2^nВремя (1 оп = 1 мкс)Масштаб
122 мксмгновенно
53232 мксмгновенно
101,024~1 мсбыстро
201,048,576~1 секприемлемо
301,073,741,824~18 минмедленно
40~1.1 трлн~12 днейнепригодно

График сложности (логарифмическая шкала)

Операции (log₁₀)
        |
  10¹⁵  |                                 ●  O(2ⁿ)
        |                              ●
  10¹²  |                           ●
        |                        ●
  10⁹   |                     ●
        |                  ●
  10⁶   |               ●
        |            ●
  10³   |     ● ● ●  O(n³)
        | ● ●●  O(n²)
   10   |●  O(n)
        |
    1   +-------------------------------------------->
          5   10   15   20   25   30   35       n

Практические ограничения

Максимально допустимые размеры:

  • n = 20: выполнимо за секунды ✅
  • n = 30: выполнимо за минуты ⚠️
  • n = 40: выполнимо за часы/дни ❌
  • n > 50: практически невыполнимо ❌❌

Важно помнить

✅ Часто можно оптимизировать до O(n) или O(n²) ✅ Используйте мемоизацию для рекурсивных решений ❌ Непригодно для n > 25-30 ❌ Наивные рекурсивные решения часто дают O(2ⁿ)

Примеры кода

Рекурсивный Фибоначчи (наивный)

function fibonacci(n) {
  if (n <= 1) {
    return n;
  }
 
  return fibonacci(n - 1) + fibonacci(n - 2);
}
 
console.log(fibonacci(5));  // 5
console.log(fibonacci(10)); // 55
console.log(fibonacci(40)); // Очень долго!

Генерация всех подмножеств

function getAllSubsets(arr) {
  const result = [[]];
 
  for (const element of arr) {
    const length = result.length;
 
    for (let i = 0; i < length; i++) {
      result.push([...result[i], element]);
    }
  }
 
  return result;
}
 
console.log(getAllSubsets([1, 2, 3]));
// Всего: 2³ = 8 подмножеств