题意:
有一个由底至上为从大到小放置的 n 个圆盘,和三个柱子(分别为左/中/右即left/mid/right),开始时所有圆盘都放在左边的柱子上,
现要求我们要把所有的圆盘都移到右边的柱子上,要求一次只能移动一个圆盘,而且大的圆盘不可以放到小的上面。
请实现一个函数打印最优移动轨迹。
方法一:
递归
思路:将大规模问题递归分解成小规模问题。步骤:
1.将个圆盘从 左边柱子 借助 右边柱子 移动到 中间柱子;
2.将个圆盘从 左边柱子 直接 移动到 右边柱子;
3.将个圆盘从 中间柱子 借助 左边柱子 移动到 右边柱子。
class Solution {
public:
vector<string> res;
vector<string> getSolution(int n) {
f(n,"left","mid","right");
return res;
}
void f(int n,string x,string y,string z){//递归实现
if(n==0)//如果n==0,结束
return;
f(n-1,x,z,y);//将上面的n-1个圆盘从左边柱子借助右边柱子移动到中间柱子
res.push_back("move from "+x+" to "+z);//将最下面的1个圆盘从左边柱子直接移动到右边柱子
f(n-1,y,x,z);//将n-1个圆盘从中间柱子借助左边柱子移动到右边柱子
}
};
时间复杂度:
空间复杂度:![]()
方法二:
非递归
思路:用栈实现非递归算法。根据方法一的递归写法,创建一个结构体表示递归节点的参数。
并参照一下顺序入栈:
struct node{//结构体
int n;
string x;
string y;
string z;
};
class Solution {
public:
vector<string> getSolution(int n) {
vector<string> res;
stack<node> st;//栈
st.push({n,"left","mid","right"});//入栈
while(!st.empty()){
auto now=st.top();
st.pop();
n=now.n;
string x=now.x;
string y=now.y;
string z=now.z;
if(n==1){//当只有一个圆盘时
res.push_back("move from "+x+" to "+z);
}else{
st.push({n-1,y,x,z});
st.push({1,x,y,z});
st.push({n-1,x,z,y});
}
}
return res;
}
}; 时间复杂度:
空间复杂度:



京公网安备 11010502036488号