递归程序优化

时间:2012-02-12 19:32:07

标签: algorithm recursion

如何编写从1到n计数的函数countTo(n)并打印每个数字而不使用显式循环(仅递归)?

解决方案必须在空间和时间上渐近最优,即使没有尾调用优化,任意大n

注意:最佳时间复杂度为 O (1),而最佳空间复杂度为 O (log n ) - 即使在迭代的情况,因为需要打印(任意大的)数字。

问题来自lesswrong.com,相关细节来自那里的讨论(否则问题变得无法回答,因为他们的原始陈述会产生误导性的假设)。

4 个答案:

答案 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)),如果我们将每个数字的打印花费相同的时间。