Python 时间复杂度为 O(n) 的斐波那契递归(而不是迭代)?
Python Fibonacci recursion (and not iteration) with O(n) time?
我知道我的 Python 斐波那契算法的简单版本的时间复杂度为 O(2^n)^2:
def fibonacci_naive(n):
if n < 0:
return None
if n == 0 or n == 1:
return 0
if n == 2:
return 1
return fibonacci_naive(n - 1) + fibonacci_naive(n - 2)
我正在尝试编写另一个 Fibonacci 递归,但复杂度为 O(n)。到目前为止,我可以想到如何用一个简单的 for
循环来做到这一点,但我无法理解如何将它变成一个递归函数。感谢您的帮助!
def fibonacci_fast(n):
if n < 0:
return None
if n == 0 or n == 1:
return 0
if n == 2:
return 1
fn_minus_2 = 0
fn_minus_1 = 1
for _ in range(2, n+1):
temp = fn_minus_2 + fn_minus_1
fn_minus_2 = fn_minus_1
fn_minus_1 = temp
return fn_minus_1
def fibonacci_fast(n, fn_minus_1=1, fn_minus_2=0):
if n < 0:
return None
if n == 0 or n == 1:
return 0
if n == 2:
return 1
return fibonacci_fast(???)
您需要使用迭代过程,例如:
def fib_r(n, depth=2, minus_1=1, minus_2=0):
if n == 0:
return 0
elif n == 1:
return 1
elif depth < n:
return fib_r(n=n, depth=depth+1, minus_1=minus_1 + minus_2, minus_2=minus_1)
else:
return minus_1 + minus_2
只是为了向您展示,这里是与使用迭代的版本进行比较,基本上,递归充当我们的循环:
In [1]: def fib(n):
...: a, b = 0, 1
...: for _ in range(n):
...: a, b = b, a+b
...: return a
...:
In [6]: def fibr(n, depth=2, a=1, b=0):
...: if n == 0:
...: return 0
...: elif n == 1:
...: return 1
...: elif depth < n:
...: return fibr(n=n, depth=depth+1, a=a+b, b=a)
...: else:
...: return a + b
...:
...:
In [3]: all(fib(i) == fibr(i) for i in range(1000))
Out[3]: True
因此,每个人都应该阅读 Ableson 和 Sussman 的 Structure and Interpretation of Computer Programs。
事实上,麻省理工学院免费提供PDF:
https://web.mit.edu/alexmv/6.037/sicp.pdf
开始阅读第 1.2.1 节,了解线性递归过程与迭代递归过程(有效的解决方案)以及图递归(这是朴素、低效的解决方案所使用的)。
我想你可以从中学到更多 post:
How to write the Fibonacci Sequence?
不过我还是要分享一个代码。
def fibonacci(n):
f = [0, 1] #first two nummber as 0, 1
for i in range(2, n+1): #for i from range 2 to n+1
f.append(f[i-1] + f[i-2])
return f[n]
P/S:如果我没记错的话,递归斐波那契总是 O(2^n) / 指数
您可以使用默认参数来向前移动序列并使用递归来递减元素数量:
def fibo(N,a=0,b=1): return fibo(N-1,b,a+b) if N else a
您可以使用相同的方法获取序列的前 N 个值:
def fibo(N,a=0,b=1): return [a] + fibo(N-1,b,a+b) if N else []
我知道我的 Python 斐波那契算法的简单版本的时间复杂度为 O(2^n)^2:
def fibonacci_naive(n):
if n < 0:
return None
if n == 0 or n == 1:
return 0
if n == 2:
return 1
return fibonacci_naive(n - 1) + fibonacci_naive(n - 2)
我正在尝试编写另一个 Fibonacci 递归,但复杂度为 O(n)。到目前为止,我可以想到如何用一个简单的 for
循环来做到这一点,但我无法理解如何将它变成一个递归函数。感谢您的帮助!
def fibonacci_fast(n):
if n < 0:
return None
if n == 0 or n == 1:
return 0
if n == 2:
return 1
fn_minus_2 = 0
fn_minus_1 = 1
for _ in range(2, n+1):
temp = fn_minus_2 + fn_minus_1
fn_minus_2 = fn_minus_1
fn_minus_1 = temp
return fn_minus_1
def fibonacci_fast(n, fn_minus_1=1, fn_minus_2=0):
if n < 0:
return None
if n == 0 or n == 1:
return 0
if n == 2:
return 1
return fibonacci_fast(???)
您需要使用迭代过程,例如:
def fib_r(n, depth=2, minus_1=1, minus_2=0):
if n == 0:
return 0
elif n == 1:
return 1
elif depth < n:
return fib_r(n=n, depth=depth+1, minus_1=minus_1 + minus_2, minus_2=minus_1)
else:
return minus_1 + minus_2
只是为了向您展示,这里是与使用迭代的版本进行比较,基本上,递归充当我们的循环:
In [1]: def fib(n):
...: a, b = 0, 1
...: for _ in range(n):
...: a, b = b, a+b
...: return a
...:
In [6]: def fibr(n, depth=2, a=1, b=0):
...: if n == 0:
...: return 0
...: elif n == 1:
...: return 1
...: elif depth < n:
...: return fibr(n=n, depth=depth+1, a=a+b, b=a)
...: else:
...: return a + b
...:
...:
In [3]: all(fib(i) == fibr(i) for i in range(1000))
Out[3]: True
因此,每个人都应该阅读 Ableson 和 Sussman 的 Structure and Interpretation of Computer Programs。
事实上,麻省理工学院免费提供PDF:
https://web.mit.edu/alexmv/6.037/sicp.pdf
开始阅读第 1.2.1 节,了解线性递归过程与迭代递归过程(有效的解决方案)以及图递归(这是朴素、低效的解决方案所使用的)。
我想你可以从中学到更多 post:
How to write the Fibonacci Sequence?
不过我还是要分享一个代码。
def fibonacci(n):
f = [0, 1] #first two nummber as 0, 1
for i in range(2, n+1): #for i from range 2 to n+1
f.append(f[i-1] + f[i-2])
return f[n]
P/S:如果我没记错的话,递归斐波那契总是 O(2^n) / 指数
您可以使用默认参数来向前移动序列并使用递归来递减元素数量:
def fibo(N,a=0,b=1): return fibo(N-1,b,a+b) if N else a
您可以使用相同的方法获取序列的前 N 个值:
def fibo(N,a=0,b=1): return [a] + fibo(N-1,b,a+b) if N else []