如何编写从1到n计数的函数countTo(n)
并打印每个数字而不使用显式循环(仅递归)?
解决方案必须在空间和时间上渐近最优,即使没有尾调用优化,任意大n
。
注意:最佳时间复杂度为 O (1),而最佳空间复杂度为 O (log n ) - 即使在迭代的情况,因为需要打印(任意大的)数字。
问题来自lesswrong.com,相关细节来自那里的讨论(否则问题变得无法回答,因为他们的原始陈述会产生误导性的假设)。
答案 0 :(得分:5)
如果您希望重写版本仍然是递归的,那就没办法了。任何函数调用都会占用堆栈空间。
有些语言处于尾部位置的调用不会消耗堆栈空间。在这些语言中,您可以将函数重写为尾递归,因此它将在O(1)空间中运行。但是,Python不是这些语言之一。
答案 1 :(得分:1)
使用迭代而不是递归。
def countTo(n):
for i in range(1, n + 1):
print(n)
答案 2 :(得分:1)
如果python支持尾递归,你可以这样做:
def foo(n):
print n
if n > 1:
foo(n-1)
任何现代gcc版本的相应c程序都将在O(1)中运行。我不知道任何支持尾递归的python解释器 - 但是我没有看到语言本身有任何限制它会禁止它。
答案 3 :(得分:0)
def foo(n):
if n > 1:
foo(n-1)
print n
(将其视为算法,而非语言特定代码。)
这里的时间复杂度将是O(n * log(n)),如果我们将每个数字的打印花费相同的时间。