Space 具有记忆功能的递归河内塔的复杂性?

Space complexity of recursive Towers of Hanoi with memoization?

使用记忆化的河内递归塔的 space 复杂度是多少?

我猜递归算法有 2^(n-1) 次递归调用,所以 space-复杂度是 2^(n-1)?

阅读下面的一些评论后编辑:我认为这里没有重复的递归调用,所以记忆根本没有帮助。如果我使用记忆,所有递归调用都将被存储,因此将 space-复杂性提高到最大值:2^(n-1)。这个递归算法最好不要使用记忆化吗?

你能证实我的理由吗?

汉诺塔问题:列表移动以使用“中间”挂钩将 n 个圆盘从“源”挂钩移动到“目标”挂钩。

递归算法:

def hanoi_tower_solution(n, source, mid, target):
    if n == 1:
        disk_move(source, target)
    else:
        hanoi_tower_solution(n-1, source, target, mid)
        disk_move(source, target)
        hanoi_tower_solution(n-1, mid, source, target)

I guess the recursive algorithm has 2−1 recursive calls, so the space-complexity is 2−1?

没有。尽管有那么多调用,但在进行下一次递归调用之前仍有调用返回,因此前一次调用使用的(堆栈)内存首先被释放,然后再次使用。

重要的是递归的最深深度。由于 −1 作为参数传递,并且等于 1 到达递归的最深点,深度为 .因此 space 复杂度为 O()。

If I use memoization, all the recursive calls will be stored and hence raise the space-complexity to the maximum: 2−1.

正确。

Is it better not to use memoization for this recursive algorithm?

这取决于记忆的具体内容。如果塔的简单状态被用作键,那么它是无用的,因为在解决方案中没有状态出现两次。

我们可以想象一种记忆,其中塔的顺序不在键中表示,并且仅使用一个堆栈中顺序的、最小的圆盘的数量作为键——这个子堆栈必须搬到另一个地方。将 3 个最小的圆盘从 B 塔移动到 C 的移动可以使用记忆解决方案将它们从 A 塔移动到 B。然后您将注意移动的编码方式,以便它们正确地转换为实际情况的塔。然后这将需要大约 O() 条目来记忆,但每个条目都会列出要进行的移动,这在要移动的圆盘数量方面再次呈指数...

记忆化确实没有太大好处,因为:

  1. 总之2−1步必须走完,所以没有时间增益。
  2. 有一个不需要递归的直接解决方案:棋子的数量、当前状态和着法编号唯一地定义了必须下的着法。 Wikipedia 上解释了该逻辑。然后它以恒定的辅助 space 复杂度运行(因此不计算用于表示当前状态的内存)。