Пространственная сложность рекурсивной функции

учитывая функцию ниже:

int f(int n) {
  if (n <= 1) {
    return 1;
  }
  return f(n - 1) + f(n - 1);
} 

Я знаю, что большая сложность времени O O(2^N), потому что каждый звонок вызывает функцию дважды.

чего я не понимаю, так это почему сложность пространства / памяти O(N)?

1 ответов


полезный способ подойти к этим типам проблем-думать о рекурсия дерево. Две особенности рекурсивной функции для идентификации:

  1. глубина дерева (сколько всего возвращение заявления будет выполняться до базового случая)
  2. ширина дерева (сколько всего рекурсивные вызовы функций будет сделано)

наши повторения отношение для этого случая T(n) = 2T(n-1). Как вы правильно отметили сложность времени, если O(2^n) но давайте посмотрим на это по отношению к нашему дереву повторения.

      C
     / \         
    /   \      
T(n-1)  T(n-1)

            C
       ____/ \____
      /           \
    C              C   
   /  \           /  \
  /    \         /    \
T(n-2) T(n-2) T(n-2)  T(n-2)

этот шаблон будет продолжаться до нашего базового случая, который будет выглядеть такой.

С каждым последующим уровнем дерева наш n уменьшается на 1. Таким образом, наше дерево будет иметь глубина n прежде чем он достигнет базового варианта. Поскольку каждый узел имеет 2 ветви, и у нас есть n общих уровней, наш общий количество узлов -2^n наше время сложности O(2^n).

наша сложность памяти определяется количеством операторов return, потому что каждый вызов функции будет храниться в стеке программы. Чтобы обобщить, сложность памяти рекурсивной функции равна O(recursion depth). Как предполагает наша глубина дерева, у нас будет n полных операторов возврата, и, следовательно, сложность памяти O(n).