I coded three versions of the fibonacci sequence and I'm not quite sure about their time/space complexities (and why):
Variant 1: Head recursion
 int fibonacci_h(int n) {
  if (n == 1 || n == 2) {
    return 1;
  }
  return fibonacci_h(n - 1) + fibonacci_h(n - 2);
}
Variant 2: Tail recursion
int fibonacci_t(int n, int s_last = 0, int last = 1) {
  if (n == 1) {
    return last;
  }
  return fibonacci_t(n - 1, last, s_last + last);
}
Variant 3: Head recursion with cache
int fibonacci_hash(int n, unordered_map<int, int>* fib_hash = new unordered_map<int, int>{{1, 1},{2, 1}}) { 
  if((*fib_hash).find(n)!=((*fib_hash).end())){
    return  (*fib_hash)[n];
  }
  int result = fibonacci_hash(n - 1, fib_hash) + fibonacci_hash(n - 2, fib_hash);
  (*fib_hash)[n] = result;
  return result;
} 
Usage
int main() {
  int n = 10;
  cout << fibonacci_h(n) << endl;
  cout << fibonacci_t(n) << endl;
  cout << fibonacci_hash(n) << endl;
} // Output: 55
Greatly appreciated!
 
     
    
