Étant donné la fonction ci-dessous:
int f(int n) {
if (n <= 1) {
return 1;
}
return f(n - 1) + f(n - 1);
}
Je sais que la complexité temporelle de Big O est O(2^N)
, car chaque appel appelle la fonction deux fois.
Ce que je ne comprends pas, c'est pourquoi la complexité espace/mémoire est O(N)
?
Une façon utile d'aborder ces types de problèmes est de penser à arbre de récursivité . Les deux caractéristiques d'une fonction récursive à identifier sont:
Notre relation de récurrence pour ce cas est T(n) = 2T(n-1)
. Comme vous avez correctement noté la complexité temporelle de O(2^n)
mais regardons-la en relation avec notre arbre de récurrence.
C
/ \
/ \
T(n-1) T(n-1)
C
____/ \____
/ \
C C
/ \ / \
/ \ / \
T(n-2) T(n-2) T(n-2) T(n-2)
Ce modèle se poursuivra jusqu'à notre scénario de base qui ressemblera à comme ceci .
À chaque niveau d'arbre successif, notre n diminue de 1. Ainsi, notre arbre aura une profondeur de n avant d'atteindre le cas de base. Puisque chaque nœud a 2 branches et que nous avons n niveaux totaux, notre nombre total de nœuds est 2^n
Ce qui rend notre complexité temporelle O(2^n)
.
Notre complexité de mémoire est déterminée par le nombre d'instructions de retour car chaque appel de fonction sera stocké sur la pile de programmes. Pour généraliser, la complexité de la mémoire d'une fonction récursive est O(recursion depth)
. Comme le suggère notre profondeur d'arbre, nous aurons n déclarations de retour total et donc la complexité de la mémoire est O(n)
.