题意:
有一个由底至上为从大到小放置的 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; } };
时间复杂度:
空间复杂度: