列出所有下楼梯路径的时间复杂度?

Posted

技术标签:

【中文标题】列出所有下楼梯路径的时间复杂度?【英文标题】:Time complexity of listing all paths down stairs? 【发布时间】:2020-03-15 22:11:13 【问题描述】:

我无法确定爬楼梯问题的回溯解决方案的时间复杂度

你正在爬楼梯。到达顶部需要 n 步。

每次您可以爬 1 或 2 级台阶。您可以通过多少种不同的方式登顶?

注意:给定 n 将是一个正整数。

输入:2

输出:2

解释:有两种方法可以爬到 顶。

    1 步 + 1 步 2 步

我的算法:

input = [1, 2]
output = set()
n = 4
def helper(temp):
    if sum(temp) == n:
        output.add(tuple(temp))
    elif sum(temp) > n:
        return
    else:
        for i in input:
            helper(temp + [i])
helper([])

print(output)

n = 4 的输出:

(1, 2, 1), (2, 1, 1), (1, 1, 2), (2, 2), (1, 1, 1, 1)

【问题讨论】:

【参考方案1】:

这个函数的运行时间是不寻常的 Θ(n · φn),其中 φ 是 黄金比例,(1 + √5) / 2。

要了解这是为什么,让我们谈谈如何分析您编写的代码。想象一下这段代码的递归树。 (这是每个递归调用都有一个节点的树)。请注意,每个递归调用都会分支 - 一次调用大小为 n - 1 的子问题,一次调用大小为 n - 2 的问题。在每个内部节点都在分支的任何树中,总节点数最多为两倍叶数。在您的情况下,找到的每个解决方案都有一个叶子,当递归超过 n 的值时,还有一些额外的叶子。 (现在,我们将忽略第二组,但我们稍后会讨论为什么会这样。)这意味着递归调用的总数(前面的警告稍后解决)最多是路径数的两倍下楼梯。

那么这个问题有多少解决方案呢?结果表明,高度为 n 的楼梯的解数是exactly equal to the nth Fibonacci number,而第 n 个斐波那契数恰好是 Θ(φn)。这意味着总共进行了 Θ(φn) 次递归调用。

那么这些递归调用需要做多少工作?我们可以在 O(n) 上保守地对每个递归调用的工作进行上限,因为在最坏的情况下,将列表加起来 1 + 1 + 1 + ... + 1 n 次。但是我们也可以在 Ω(n) 处将工作量最大的叶子上的功下限,因为在最好的情况下,我们将 2 + 2 + ... + 2 加起来总共 n / 2 次。

总的来说,我们有 Θ(φn) 调用,其中底部的调用每个都 Θ(n) 工作,总共 Θ(n · φn) 工作。

还有最后一个细节需要解决——“过冲”并加起来大于 n 的递归调用呢?事实证明,其中也有 O(φn) 个。看到这一点的一种方法是,达到 n + 1 的超调方式的数量最多是列出所有大小为 n + 1 的路径的解决方案的数量,并且有 O(φn)这些。所以重新添加这些并不会改变任何东西。

希望这会有所帮助!

【讨论】:

你能解释一下这个问题φ是否可以用2代替吗?因为这里有两个分支因子? 在这里使用 2 作为上限,因为 n * phi^n

以上是关于列出所有下楼梯路径的时间复杂度?的主要内容,如果未能解决你的问题,请参考以下文章

Min Cost Climbing Stairs [746]

爬楼梯

程序员面试金典面试题 08.01. 三步问题

哈密 顿路径算法时间复杂度

算法1.1

在 MVC 3 中渲染复杂视图