Какие проблемы возникнут при рекурсивном вычислении миллионного числа Фибоначчи?

«Какие проблемы возникнут при рекурсивном вычислении миллионного числа Фибоначчи?» — вопрос из категории Алгоритмы и структуры данных, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Наивная рекурсивная реализация (fib(n) = fib(n-1) + fib(n-2)) для n = 1'000'000 неприменима из-за фундаментальных проблем:

  1. Экспоненциальная временная сложность O(2ⁿ). Число операций растёт невообразимо быстро. Даже для n=50 вычисление становится крайне долгим, а для миллиона — практически бесконечным.

  2. Переполнение стека вызовов (Stack Overflow). Глубина рекурсии равна n. Стек программы ограничен (обычно 1-8 МБ), и вызов миллиона вложенных функций неизбежно исчерпает его.

Практическое решение на C++: Для вычисления больших чисел Фибоначчи используется итеративный алгоритм с длинной арифметикой.

  • Итеративный подход (O(n) по времени, O(1) по памяти):

    #include <vector>
    // Используем вектор для хранения цифр (простая модель длинной арифметики)
    std::vector<int> addBigInts(const std::vector<int>& a, const std::vector<int>& b);
    
    std::vector<int> fibonacci_iterative(int n) {
        if (n <= 1) return {n};
        std::vector<int> a = {0};
        std::vector<int> b = {1};
        std::vector<int> c;
        for (int i = 2; i <= n; ++i) {
            c = addBigInts(a, b); // c = a + b
            a = std::move(b);
            b = std::move(c);
        }
        return b;
    }
  • Для миллионного числа результат будет содержать примерно 208'988 цифр в десятичной системе. Потребуется эффективная реализация длинной арифметики (например, через std::vector<uint32_t> в системе счисления по основанию 10⁹) и, возможно, использование алгоритма быстрого возведения матрицы в степень (O(log n)), чтобы ускорить расчёт.