Here is a close-form Python solution which is O(1). It uses Binet's formula (from the Wikipedia article that you linked to):
>>> from math import sqrt,log
>>> def numFibs(n): return int(log(sqrt(5)*n)/log((1+sqrt(5))/2))
>>> numFibs(10)
6
Which tracks with 1,1,2,3,5,8
The point is that the second term in Binet's formula is negligible and it is easy enough to invert the result of neglecting it.
The above formula counts the number of Fibonacci numbers which are less than or equal to n
. It jumps by 1 with each new Fibonacci number. So, for example, numFibs(12) = 6
and numFibs(13) = 7
. 13 is the 7th Fibonacci number, so if you want the number of Fibobacci numbers which are strictly smaller than n
you have to introduce a lag. Something like:
def smallerFibs(n):
if n <= 1:
return 0
else:
return min(numFibs(n-1),numFibs(n))
Now smallerFibs(13)
is still 6 but then smallerFibs(14) = 7.
This is of course still O(1)
.