面试题答案
一键面试递归函数实现
#include <iostream>
// 汉诺塔递归函数
void hanoi(int n, char source, char auxiliary, char target) {
if (n > 0) {
// 将n - 1个圆盘从source移动到auxiliary
hanoi(n - 1, source, target, auxiliary);
// 将第n个圆盘从source移动到target
std::cout << "Move disk " << n << " from " << source << " to " << target << std::endl;
// 将n - 1个圆盘从auxiliary移动到target
hanoi(n - 1, auxiliary, source, target);
}
}
时间复杂度分析
汉诺塔问题的递归函数时间复杂度为$O(2^n)$。
- 每次递归调用
hanoi
函数时,会产生两个子问题,即移动$n - 1$个圆盘的操作。 - 随着$n$的增加,问题规模呈指数增长。对于$n$个圆盘,总的移动次数为$2^n - 1$。因此,时间复杂度为$O(2^n)$。
空间复杂度优化
- 递归调用栈空间:原递归实现中,空间复杂度主要来自递归调用栈,最坏情况下为$O(n)$,因为递归深度最大为$n$。
- 优化方法 - 迭代实现:可以使用栈(模拟递归调用栈)来实现迭代版本的汉诺塔算法,从而将空间复杂度优化到$O(1)$。具体思路是:
- 用一个栈来模拟递归调用过程。
- 每个栈元素记录当前任务的状态,包括当前要移动的圆盘数量、源柱、辅助柱和目标柱。
- 通过循环和栈操作来模拟递归调用,避免直接的递归调用。
示例代码如下(迭代实现汉诺塔):
#include <iostream>
#include <stack>
struct HanoiTask {
int n;
char source;
char auxiliary;
char target;
HanoiTask(int n, char source, char auxiliary, char target) : n(n), source(source), auxiliary(auxiliary), target(target) {}
};
void hanoiIterative(int n, char source, char auxiliary, char target) {
std::stack<HanoiTask> taskStack;
taskStack.push(HanoiTask(n, source, auxiliary, target));
while (!taskStack.empty()) {
HanoiTask task = taskStack.top();
taskStack.pop();
if (task.n > 0) {
taskStack.push(HanoiTask(task.n - 1, task.auxiliary, task.source, task.target));
std::cout << "Move disk " << task.n << " from " << task.source << " to " << task.target << std::endl;
taskStack.push(HanoiTask(task.n - 1, task.source, task.target, task.auxiliary));
}
}
}
这样,通过迭代实现,空间复杂度可以优化到$O(1)$。