我一直在研究一种方法,该方法可以根据响铃次数自动返回可以在河内塔游戏中进行的最小移动次数。到目前为止,我有基本代码可以计算2 ^ n(n是环的数量)。但是,当我去减1时,该方法表现得好像它们没有环。
static int countHanoiMoves(int n)
{
int unSubtrctAnswer = 0;
if(n == 0)
{
return 1;
}
int halfPower = countHanoiMoves(n / 2);
if (n % 2 == 1)
{
unSubtrctAnswer = (2 * halfPower * halfPower);
}
else
{
unSubtrctAnswer = (halfPower * halfPower);
}
return unSubtrctAnswer - 1;
}
答案 0 :(得分:0)
正如Andreas在评论中所建议的,您的算法不正确。递归解决方案实际上相当简单。
考虑: 要移动 n 环,首先需要移动底部顶部的所有环(n - 1),然后移动底部环(+ 1),然后重新移动所有其他环顶部(再次n - 1)。
因此...
static int countHanoiMoves(int n) {
if (n == 0) return 0;
if (n < 0) throw new RuntimeException("What? A negative number of rings?");
// count(n-1) + 1 + count(n-1)... since we aren't actually moving
// the rings, but merely counting the number of moves, we can do
// it a little more cheaply by just multiplying by 2 rather than
// calling the recursive method twice
return 2 * countHanoiMoves(n - 1) + 1;
}
请注意,您将快速超出int
的限制,因此如果您需要计算大量响铃的计数,将返回类型更改为long
会让您多呼吸一下室。