How do I implement a recursive Fibonacci function with no loops running in O(n)?
-
Do you know how to get the third Fibonacci number? Fourth? Fifth? – Ignacio Vazquez-Abrams Mar 01 '14 at 07:03
-
"it must call a recursive helper function" - what? Why? The iterative approach is much easier. I suppose they want a recursive formulation of the iterative version's loop. – user2357112 Mar 01 '14 at 07:04
-
@Mat.S: What is "not allowed linear" supposed to mean? – user2357112 Mar 01 '14 at 07:06
-
@user2357112 Sorry, these are just the specifications. I cant use any loops but it still has to be linear. – Mat.S Mar 01 '14 at 07:07
-
The hint: return two numbers, last and previous. – 9000 Mar 01 '14 at 07:07
-
@Mat.S Is it a homework? – thefourtheye Mar 01 '14 at 07:08
-
1Return two fibonacci numbers. – user2357112 Mar 01 '14 at 07:17
-
what do you mean about "no loops running in O(n)" ???? – Validus Oculus Feb 14 '15 at 16:17
4 Answers
Typically I'd be against posting an answer to a homework question like this, but everything posted so far seems to be overcomplicating things. As said in the comments above, you should just use recursion to solve the problem like you would do iteratively.
Here's the iterative solution:
def fib(n):
a, b = 0, 1
while n > 0:
a, b = b, a+b
n -= 1
return a
Here's an equivalent recursive solution:
def fib(n):
def fib_help(a, b, n):
return fib_help(b, a+b, n-1) if n > 0 else a
return fib_help(0, 1, n)
Note that in both cases we actually compute up to Fn+1, but return Fn as the result. This fits nicely with the "hint" you were given.
I hope that you'll take the time to compare the two solutions and convince yourself that they're equivalent. Understanding how to transform an iterative solution to an equivalent recursive one (or vice versa) is a good skill to develop.

- 32,589
- 6
- 74
- 101
-
Tail recursive form, eh? This is another good way to do it. Very useful skill in Scheme or other functional languages, and good to know just for the perspective it gives you. Not always the most practical transformation in Python, but neither is the solution the hint intends. – user2357112 Mar 01 '14 at 07:34
-
10No need for fib_help if you give a and b to fib as default parameters: `def fib(n, a=0, b=1):` and `return fib(n-1, b, a+b) if n > 0 else a` – gens Jul 20 '16 at 21:52
Scala code for finding nth Fibonacci Number. For more information on Tail Recursion http://nerds.logdown.com/posts/1406258-n-th-fibonacci-number
object Main {
def main(args: Array[String]) {
println(fib(9));
println(fib(8));
println(fib(7));
println(fib(6));
println(fib(5));
println(fib(4));
println(fib(3));
println(fib(2));
println(fib(1));
println(fib(0));
}
def fib(n: Int): Int = {
def fib(n: Int, p :Int, c: Int): Int ={
if (n == 0) return -1; // undefined
if (n == 1) return p;
fib(n-1, c, p + c)
}
fib(n, 0, 1);
}
}

- 161
- 1
- 6
In case someone is looking for a JavaScript solution:
function _fib(n, left, right) {
switch (n) {
case 0: return 0
case 1: return right
default: return _fib(n - 1, right, left + right)
}
}
function fib(n) {
return _fib(n, 0, 1)
}
That runs in O(n) time and O(1) space with tail call optimization.

- 3,072
- 2
- 27
- 35
To solve this in linear time, you must use a dynamic programming technique known as memoization.
The algorithm for Fibonacci in pseudo-code, using memoization, looks like this:
memoryMap[n]
func fib(int n)
if (n is in memoryMap) then
return memoryMap[n]
if (n <= 1) then
memoryMap[n] = n
else
memoryMap[n] = fib(n-1) + fib(n-2)
return memoryMap[n]
To explain, you after each call to fib(x) you be storing the result in a memory map. For each subsequent call, all lookups to fib(x) will be free: that is, looking up the result in the memory costs only O(1) time.

- 27
- 2
-
1This is a way to do it, and the first way that came to mind for me too, but not the intended solution. How much of a good or bad thing that is is a matter of opinion, but if the OP uses this, I would recommend the OP also figure out and submit the intended solution. – user2357112 Mar 01 '14 at 07:26
-
1Reading it again it was obvious the correct solution was a tail-recursion. But then again, it still doesn't make much sense, as Python doesn't even support tail-recursion elimination. – 831 Mar 01 '14 at 08:10
-
It does make sense even without tail recursion as that it only uses `n` recursive calls which should fit onto the stack for `fib`. Compare that to the naive recursion `fib(n) = fib(n-1) + fib(n-2) if n >1 else n` – kap Mar 22 '17 at 20:52
-
1I feel this _memoization_ is a natural thing to do, in order to avoid computing things multiple times, you save those results of computations somewhere, where you can look up the results in the future. It seems to me that calling it "dynamic programming" adds a lot of steam to something very simple. A version without using mutation or assignments would be interesting. – Zelphir Kaltstahl Jul 16 '17 at 12:10