面试题 08.06. 汉诺塔问题(非递归实现汉诺塔问题)

题目:

在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制:
(1) 每次只能移动一个盘子;
(2) 盘子只能从柱子顶端滑出移到下一根柱子;
(3) 盘子只能叠在比它大的盘子上。

请编写程序,用栈将所有盘子从第一根柱子移到最后一根柱子。

你需要原地修改栈。

示例1:

输入:A = [2, 1, 0], B = [], C = []
输出:C = [2, 1, 0]
示例2:

输入:A = [1, 0], B = [], C = []
输出:C = [1, 0]
提示:

A中盘子的数目不大于14个。

解答:

注意递归版本中调用顺序是:

f(n-1,a,c,b)    //1

f(1,a,b,c)    //2

f(n-1,b,a,c)    //3

所以压入栈的顺序应该是:3->2->1,这样实际的执行顺序才是:1->2->3。

class Solution {
public:
    struct ope{
        int num;
        vector<int>* from,*pass,*to;
        ope(int n,vector<int>* a,vector<int>* b,vector<int>* c):num(n),from(a),pass(b),to(c){}
        void single_transfer(){
            to->push_back(from->back());
            from->pop_back();
        }
    };
    void hanota(vector<int>& A, vector<int>& B, vector<int>& C) {
        int n=A.size();
        stack<ope> sta;
        sta.push(ope(n,&A,&B,&C));
        while(not sta.empty()){
            auto cur=sta.top();
            sta.pop();
            if(cur.num==1){
                cur.single_transfer();
            }
            else{
                sta.push(ope(cur.num-1,cur.pass,cur.from,cur.to));//bac
                sta.push(ope(1,cur.from,cur.pass,cur.to));//abc
                sta.push(ope(cur.num-1,cur.from,cur.to,cur.pass));//acb
            }
            // cout<<endl<<"A:";
            // for(int x:A){cout<<x<<" ";}
            // cout<<endl<<"B:";
            // for(int x:B){cout<<x<<" ";}
            // cout<<endl<<"C:";
            // for(int x:C){cout<<x<<" ";}
        }
    }
};

时间很慢:

猜你喜欢

转载自www.cnblogs.com/FdWzy/p/12638193.html