Самая большая проблема в ряду фибоначчи - сложность времени алгоритма при использовании простой рекурсии, вы будете пересчитывать все и делать много двойной работы. Это происходит потому, что при вычислении FIB (п) с использованием
int fib(int n) {
if (n < 2) { return 1; }
return fib(n-1) + fib(n-2)
}
вы будете вычисления FIB (п-1), который вычисляет FIB (п-2) и FIB (п-3). Но для вычисления fib (n) вы уже вычисляете fib (n-2). Чтобы улучшить это, вам нужно будет сохранить временные результаты. Обычно это проще с использованием итерации и начиная с i = 0, до n. Таким образом, вы можете легко сохранить последние два результата и не перечитывать одни и те же значения снова и снова.
Простой способ убедиться, что алгоритм эффективен, состоит в том, чтобы попытаться решить его для нескольких более сложных примеров. Вы также можете рассчитать его более точно. Возьмите пример фибоначчи выше. Вызов fib (n) займет сложность O(fib(n)) = O(fib(n-1)) +O(fib(n-2)) + 1
(давайте просто возьмем 1 для добавления).Предположим, что O(fib(0)) = O(fib(1)) = 1
. Это означает O(fib(2)) = 3, O(fib((3)) = 5, O(fib(4)) = 9
. Как вы можете видеть, эта серия будет расти быстрее, чем сама серия фибоначчи! Это означает огромную сложность. Если у вас будет итеративный алгоритм с циклом for от 0 до n, ваша сложность будет масштабироваться в порядке n, что было бы лучше.
Для получения дополнительной информации ознакомьтесь с примечанием большой о.
Если вы используете ints или longs, вы не пойдете намного дальше, чем 60 или 70 рекурсий, так что это не имеет большого значения. И вы также можете кэшировать результаты с помощью рекурсивного метода. – assylias
Также: [recursion-or-looping?] (Http://stackoverflow.com/questions/13346424/recursion-or-looping?lq=1) – nawfal